CosmWasm으로 스마트 컨트랙트 작성하기 (3부)

소개



내 시리즈에 다시 오신 것을 환영합니다. 뒤늦게 죄송합니다. 이 부분에서 execute 계약을 발견하겠습니다.
이전 에서 execute가 스마트 계약 데이터를 변경한다고 설명했습니다.
이것을 구현해 봅시다.

스마트 계약을 실행하기 위한 메시지를 생성합니다.



먼저 ExecuteMsg에서 다음 코드를 업데이트하여 ExecuteResponsesrc/msg.rs를 정의해야 합니다.

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
    Update {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct ExecuteResponse {
    pub counter: i32,
}




ExecuteMsg는 열거형이며 Updates arm가 있습니다. 이 arm는 계약을 실행할 때 counter 변수 증분 1을 돕기 위한 것입니다.
execute.rs 폴더에 src 파일을 생성해 보겠습니다. 우리의 로직은 이 파일에 있을 것입니다.
먼저 모듈executelib.rs로 가져옵니다.

우리는 이름이 try_update_counter인 함수를 구현하고 있습니다(낙타 케이스를 사용하지 마십시오. 함수 또는 변수의 이름에 단어를 연결하기 위해 녹 사용dash을 사용합니다). 매개변수로 deps를 전달합니다. 함수는 a Result<Response, ContractError> 를 반환합니다. 기능의 모든 논리는 다음과 같습니다.

#[cfg(not(feature = "library"))]
use cosmwasm_std::{to_binary, DepsMut, Response};

use crate::error::ContractError;
use crate::msg::ExecuteResponse;
use crate::state::{State, STATE};

pub fn try_update_counter(deps: DepsMut) -> Result<Response, ContractError> {
    let current_state = STATE.load(deps.storage)?;
    let mut current_counter = current_state.counter;

    current_counter += 1;

    let new_state = State {
        counter: current_counter,
    };
    STATE.save(deps.storage, &new_state)?;

    let resp = to_binary(&ExecuteResponse {
        counter: current_counter,
    })
    .unwrap();
    Ok(Response::new().set_data(resp))
}




예, 읽고 이해하기 쉽다고 생각합니다. 계약의 현재 상태current.counter에서 카운터를 가져오고 1씩 증가시킨 다음 다시 계약 저장소에 저장하고 응답으로 반환합니다.

그러나 궁금한 점이 있습니다. 구현 위치try_update_counter . src / contract.rs를 열고 immediate 두 번째 진입점 아래의 함수로 업데이트해야 합니다.

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> {
    match msg {
        ExecuteMsg::Update {} => try_update_counter(deps),
    }
}





자, 계약의 두 번째 진입점을 구현했습니다! 논리를 테스트하는 것을 잊지 마세요!Testing module 섹션 옆에 있습니다.

테스트 모듈



아직 파일에 있음: execute.rs . 아래 코드를 맨 아래로 업데이트하십시오.

#[cfg(test)]
mod tests {
    use crate::contract::{execute, instantiate};
    use crate::msg::{ExecuteMsg, ExecuteResponse};
    use crate::state::STATE;

    use crate::msg::InstantiateMsg;
    use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
    use cosmwasm_std::to_binary;

    const ADDR: &str = "addr";

    #[test]
    fn test_execute() {
        let mut deps = mock_dependencies();
        let env = mock_env();
        let info = mock_info(ADDR, &[]);
        let expect_data = to_binary(&ExecuteResponse { counter: 1 }).unwrap();
        let expect_number = 2;

        // instantiate msg
        let msg = InstantiateMsg {};
        let _resp = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();

        // execute one time
        let msg = ExecuteMsg::Update {};
        let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        println!("Execute once!");
        assert_eq!(resp.data, Some(expect_data));

        // execute two time
        let msg = ExecuteMsg::Update {};
        let _resp = execute(deps.as_mut(), env, info, msg);
        let current_state = STATE.load(deps.as_mut().storage).unwrap();
        println!("Execute twice!");
        assert_eq!(current_state.counter, expect_number);
    }
}




모듈 테스트 및 단위 테스트 기능을 생성합니다test_execute.
우리는 여전히 모든 종속성을 가져오고 두 개의 값을 만듭니다. 하나는 try_update_counter의 응답에 대한 값은 expected_data이고 다른 하나는 우리 상태와 비교한 값인 expected_number입니다.

또한 InstantiateMsg를 가져와 상태를 생성합니다. 원인counter은 0입니다.
한 번 실행하면 execute 함수를 호출하고 카운터를 1로 업데이트하고 assert_eqresp.dataexpect_data로 업데이트합니다.
두 번 실행하고 execute 함수를 호출하고 카운터를 2로 업데이트하고 assert_eqcurrent_state.counterexpect_number로 업데이트합니다.

이해하기 매우 간단합니다.

터미널에서 cargo-test 실행



출력이 아래와 같으면 모든 것이 올바른 것입니다.

running 2 tests
test contract::tests::test_instantiate ... ok
test execute::tests::test_execute ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests cw-starter

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


1개의 테스트 케이스를 실행하고 1개는 통과했습니다.

요약



스마트 계약의 두 번째 진입점은 execute: ExecuteMsg, ExecuteResponse 및 try_update_counter입니다.
또한 이를 테스트하기 위한 모듈을 만듭니다.

다음 부분에서 마지막 진입점 명명: query에 대해 언급하겠습니다.
게시물을 읽어 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기