체인의정석

Solidity에서 enum 타입이 다뤄지는 법과 EIP712 형태의 서명에서 enum 다루기 본문

블록체인/NFT & BRIDGE

Solidity에서 enum 타입이 다뤄지는 법과 EIP712 형태의 서명에서 enum 다루기

체인의정석 2022. 7. 1. 12:02
728x90
반응형

먼저 solidity에서 enum을 정의하는 부분은 다음과 같이 진행한다.

소스는 오픈씨의 새로나온 Seaport의 스타일을 참고하여 다루었다.

 

먼저 컨트렉트 부분이다. enum을 정의하는 경로는 따로 만들어서 관리하였다. 

solidity에서 컨트렉트를 배포할 때는 어차피 통합되어 배포되기 때문에 요즘 스타일은 이런식을 많이 쓰는 것 같다.

 

Sturct 및 enum에 부분을 다음과 같이 따로 구현하였다.

/** Side
  0: order is made from seller
  1: order is made from buyer
*/

enum Side {
    SELL,
    BUY
}

 

여기에 있는 테스트 코드는 다음과 같이 작성하였다.

  it("check test Enum", async function () {
    console.log(await exchangeCore.TestEnum());
  });

  it("should ValidateOrderParameter", async function () {
    console.log("SIDE", Side.SELL);
    await expect(
      exchangeCore.validateOrderParameters(
        makeOrder(exchangeCore.address, Side.SELL, signerOne.address, 1000)
      )
    ).to.be.true;
  });

거래에 대한 파라미터가 유효한지 검사하는 부분인데 여기서 enum 타입을 넣어서 검사하려고 한다.

 

테스트코드에서 작성한 TestEnum은 다음과 같다. 컨트렉트와 똑같이 작성하며 상단에 테스트 코드에 대한 변수를 정의하는 부분에 넣으면 된다.

enum Side {
  SELL,
  BUY,
}

여기에 대해서 궁금했던 부분은 어떤 타입으로 이런 Enum이 반환되며 메타마스크 서명 때는 어떤 값으로 받아야 해당 enum이 같은 방식으로 작동하는지를 보는 것이었다.

//test code
  it("check test Enum", async function () {
    const Enum = await exchangeCore.TestEnum();
    console.log("Enum", Enum);
  });

//result
✔ should get correct signature and publicKey (50ms)
Enum 0

다음과 같이 보면 Enum이 0으로 나온 것을 볼 수 있었다.

  function TestEnumSELL () public view returns (Side) {
    return Side.SELL;
  }

  function TestEnumBUY () public view returns (Side) {
    return Side.BUY;
  }

다시 사이드를 정해주면 다음과 같이 나온다.

//test code
  it("check test Enum", async function () {
    const EnumSELL = await exchangeCore.TestEnumSELL();
    console.log("TestEnumSELL", EnumSELL);

    const EnumBUY = await exchangeCore.TestEnumBUY();
    console.log("TestEnumSELL", EnumBUY);
  });

//result
TestEnumSELL 0
TestEnumSELL 1
    ✔ check test Enum

결국 enum 타입의 경우 정의한 enum의 타입을 쓰면 되고 리턴되는것은 해당 Enum 순서의 숫자값을 받아온다.

 

해당 enum을 받아오는 메타마스크 부분의 코드는 다음과 같다.

      types: {
        Order: [
          { name: "side", type: "uint8" },
        ],
      },

해당 타입으로 넣어서 싸인을 해주고 AtomicMatch 부분의 검증은

    if (buyOrder.maker == msg.sender) {
      require(buyOrder.side == Side.BUY, "ExchangeCore: order side is wrong");

이런식으로 해주었는데 조건문을 통과하는것을 확인하였다.

 

*결론은 enum 타입을 unit8 형태로 메타마스크에서 받아오고 solidity와 타입스크립트에서는 Enum 타입으로 처리하면 서명데이터도 정상적으로 잘 받아와진다는 것이다.

728x90
반응형
Comments