체인의정석

컨트렉트에서 데이터 encode 및 decode 하기 본문

블록체인/Solidity

컨트렉트에서 데이터 encode 및 decode 하기

체인의정석 2022. 5. 22. 02:06
728x90
반응형

스마트컨트렉트에서

Encode와 Decode를 할 때는 아래와 같이 encode, decode 함수를 사용하여서  할 수 있다.

contract Encode {
function encode(string memory _string1, uint _uint, string memory _string2) public pure returns (bytes memory) {
        return (abi.encode(_string1, _uint, _string2));
    }
function decode(bytes memory data) public pure returns (string memory _str1, uint _number, string memory _str2) {
        (_str1, _number, _str2) = abi.decode(data, (string, uint, string));            
    }
}

https://medium.com/coinmonks/abi-encode-and-decode-using-solidity-2d372a03e110

 

ABI encode and decode using solidity

A smart contract is basically made up of state variables and functions. Some functions are private and can only be accessed from within the…

medium.com

https://docs.ethers.io/v5/api/utils/abi/coder/#AbiCoder--creating

 

AbiCoder

Documentation for ethers, a complete, tiny and simple Ethereum library.

docs.ethers.io

 

구현한 논문 코드

    function setTravelRuleServiceData (
        address _contractAddress,
        uint256 _tokenID,
        address _customerAddress,
        bytes32 _travelRuleServiceData,
        string memory _vaspCode
        ) public onlyRegisterd {
        registerdCustomer[msg.sender] = true;
        bytes memory encodedData = abi.encode(_travelRuleServiceData,_vaspCode);
        travelRuleServiceData[_contractAddress][_tokenID][_customerAddress] = encodedData;
    }

    function decodeDataAndVaspCode (bytes memory _encodedData) public view returns(bytes32 _travelRuleServiceData,string memory _vaspCode) {
        (_travelRuleServiceData,_vaspCode) = abi.decode(_encodedData,(bytes32, string));
    }

이런식으로 encode, decode를 하면 되며,

    describe("Travel rule service could set Travel Rule Service Data if they want", async () => {

      it("setTravelRuleServiceData to TravelRuleManager with vasp code",async () => {
        const from_customer_info = await travelRuleSolutionExample_1.UserInformation(from_customer.address);
        //user data
        let userCode = await from_customer_info.userCode;
        let userType = await  from_customer_info.userType;
        let name = await  from_customer_info.name;
        let nameID = await  from_customer_info.nameID;
        let user_address = await  from_customer_info.user_address;
        let NationalIdentification = await  from_customer_info.NationalIdentification;
        let datesAndPlacOfBirth = await  from_customer_info.datesAndPlacOfBirth;
        let customerEncodedData = await abiCoder.encode(
          ["string","string","string","string","string","string","string"],
          [userCode,userType,name,nameID,user_address,datesAndPlacOfBirth,NationalIdentification]
        )
        let encodeDatakeccack_from = await ethers.utils.keccak256(customerEncodedData);

        const to_customer_info = await travelRuleSolutionExample_2.UserInformation(to_customer.address);
        //user data
        let userCode_to = await to_customer_info.userCode;
        let userType_to = await  to_customer_info.userType;
        let name_to = await  to_customer_info.name;
        let nameID_to = await  to_customer_info.nameID;
        let user_address_to = await  to_customer_info.user_address;
        let NationalIdentification_to = await  to_customer_info.NationalIdentification;
        let datesAndPlacOfBirth_to = await  to_customer_info.datesAndPlacOfBirth;
        let customerEncodedData_to = await abiCoder.encode(
          ["string","string","string","string","string","string","string"],
          [userCode_to,userType_to,name_to,nameID_to,user_address_to,datesAndPlacOfBirth_to,NationalIdentification_to]
        )
        let encodeDatakeccack_to = await ethers.utils.keccak256(customerEncodedData_to);

        await travelRuleManager.connect(from_vasp).setTravelRuleServiceData(travelRuleNft.address,1,from_customer.address,encodeDatakeccack_from,"SDFSES123");
        await travelRuleManager.connect(to_vasp).setTravelRuleServiceData(travelRuleNft.address,1,to_customer.address,encodeDatakeccack_to,"RQGQR12313");
      })

      it("check if travel rule log is recorded", async () => {
        expect(await travelRuleNft.connect(from_customer).transferFrom(from_customer.address,to_customer.address,1))
        .to.emit(travelRuleNft,"travelRuleLog")
        .withArgs(
          await travelRuleManager.getTravelRuleServiceData(travelRuleNft.address,1,from_customer.address),
          await travelRuleManager.getTravelRuleServiceData(travelRuleNft.address,1,to_customer.address)
        );
      })

      it("travle rule log can be decoded back, check with from data", async () => {
        let encodedData_from = await travelRuleManager.getTravelRuleServiceData(travelRuleNft.address,1,from_customer.address);
        console.log(await travelRuleManager.decodeDataAndVaspCode(encodedData_from));
      })

      it("travle rule log can be decoded back, check with to data", async () => {
        let encodedData_to = await travelRuleManager.getTravelRuleServiceData(travelRuleNft.address,1,to_customer.address);
        console.log(await travelRuleManager.decodeDataAndVaspCode(encodedData_to));
      })

테스트 코드를 통해서 컨트렉트의 정보를 불러온 후 저장 하고 encode 한 후 decode 실행 

그 결과는 성공!

복잡한 데이터를 간단하게 남기고 싶을 때 이러한 encode와 decode가 매우 편리하다. 

 

이를 활용해서 논문에서도 트레블룰 정보를 구조에 맞게 encode, decode 하는 형태로 만들었다. 

728x90
반응형
Comments