수수료 대납 트랜잭션에 발신자 서명 방법 문의

Chrome 브라우저의 Kaikas를 사용하는 Page에서
아래와 같이 legacy transaction으로 동작하는 Contract의 store 함수를 수수료 대납으로 실행해 보고자 하는데요, Sign 하는 방법을 찾지 못해서 문의를 드립니다.

    let transaction = caver.transaction.feeDelegatedSmartContractExecution.create({
      from: from,
      to: to,
      gas: '300000',
      feePayer: feePayer,
      chainId: 1001,
      input: caver.abi.encodeFunctionCall({
        name: 'store',
        type: 'function',
        inputs: [ { "internalType": "uint256", "name": "num", "type": "uint256" } ],
      }, [newValue.toString()]),
    });
    console.dir(transaction);
    ....

대부분의 문서가 트랜잭션 Sender의 PrivateKey를 하드코딩 해서 서명하는 형태로 되어 있는데,
Back-office가 아닌 상용 서비스 중인 DApp에서 PrivateKey 획득 및 wallet의 keyring 구성이 가능한 것인지도 의문이 듭니다.

아니면 전적으로 (무료로는 개수 제한이 있는) Service Provider 하위에 Account들을 생성하고 별도의 Mapping 작업을 통해 연결되는 계정으로만 수수료 대납 트랜잭션을 서비스로 제공하는 형태로 가져 가야만 하는 것인지요?

[ Private Key가 Kaikas 내에만 있을 때는 수수료 대납 트랜잭션이 불가하다 ]면 빠르게 포기할 수 있겠습니다만 가능한 방법이 있다면 안내를 부탁 드립니다.

안녕하세요 @relician :smiley:
클레이튼 포럼에 방문해주셔서 감사합니다

해당 플로우는 아래와 같습니다.

  1. DApp이 Kaikas에게 FeeDelegated TX 서명 요청
  2. 사용자가 Kaikas를 통해 Signed TX 반환
  3. DApp이 Fee Payer 서명 후 EN에 제출

아래 링크의 문서와 예제를 참고해주시면 개발에 도움이 될것같습니다.
Kaikas Docs
Caver-js Docs

개발 중 궁금한 사항이 생기면 편하게 문의해주세요.
감사합니다.
좋은 하루 보내세요 :smiley:

답변 감사 드립니다. 진행 해 보겠습니다.

1 Like

@Johnny

답변 주신 내용에 따라 KAIKAS에서 서명 받아 오는 부분은 아래와 같이 해결 되었습니다.

const signedTransaction = await caver.rpc.klay.signTransaction({
    type: 'FEE_DELEGATED_SMART_CONTRACT_EXECUTION',
    from: from,
    to: to,
    data: caver.abi.encodeFunctionCall({
        name: 'store',
        type: 'function',
        inputs: [{"internalType": "uint256", "name": "num", "type": "uint256"}],
    }, [newValue.toString()]),
    gas: '300000',
    feePayer: feePayer,
});

/** signedTransaction 로그
{
    "messageHash": "0x461ffabc5df699aa791126a48bc2bffc541e1c849286c58af084d684d378045b",
    "v": "0x07f5",
    "r": "0x16bb35cf2aef7c68a87f202ba630a38d7b47ad64a262e13e9a6fb32f17d7ebef",
    "s": "0x3f97bf1f415c34e00396886befef1e916892d7f15238298c8402310ffbb75aa7",
    "rawTransaction": "0x31f8aa0e8505d21dba00830493e0947e7e54de0d34009492bc5cba3f9073198abea02a809449e8a1112b8402d45a133e61f25a8c19e96b8267a46057361d0000000000000000000000000000000000000000000000000000000000000462f847f8458207f5a016bb35cf2aef7c68a87f202ba630a38d7b47ad64a262e13e9a6fb32f17d7ebefa03f97bf1f415c34e00396886befef1e916892d7f15238298c8402310ffbb75aa780c4c3018080",
    "txHash": "0xe8f3a025b31c858e02a974500cbadc6c6c00d7181f1908203354f2cd4a82c60a",
    "senderTxHash": "0x145f54ac49377c7cd545cd6ccfbaa402b20fd8f2780b4ca1b000336da12c3855",
    "signatures": [
        [
            "0x07f5",
            "0x16bb35cf2aef7c68a87f202ba630a38d7b47ad64a262e13e9a6fb32f17d7ebef",
            "0x3f97bf1f415c34e00396886befef1e916892d7f15238298c8402310ffbb75aa7"
        ]
    ],
    "txParams": {
        "from": "0x49e8a1112b8402d45a133e61f25a8c19e96b8267",
        "to": "0x7e7e54de0d34009492bc5cba3f9073198abea02a",
        "data": "0x6057361d0000000000000000000000000000000000000000000000000000000000000462",
        "gas": "0x493e0",
        "type": "FEE_DELEGATED_SMART_CONTRACT_EXECUTION",
        "feePayer": "0x2214bac5f641b8a1c8a1942700de64474212b5d1",
        "chainId": 1001,
        "humanReadable": false,
        "gasPrice": "0x5d21dba00",
        "nonce": "0xe"
    }
}

위의 JSON 형태로 나오는 게 맞는 지 궁금하긴 한데요, 일단 내용 부분은 다음 문제일 것 같습니다.




그 전의 코드는 아래의 형태였는데요, 어떤 부분이 문제인 지가 궁금해 졌습니다.
Error Message를 보면 caver.transaction.feeDelegatedSmartContractExecution.create로 생성한 인스턴스가 FD 관련 정보를 가지고 있지 않아 sign 할 수 없다는 것 같은데요, 빠뜨린 부분이 있는 지 검토를 부탁 드립니다.

const fdExecutionTransaction = caver.transaction.feeDelegatedSmartContractExecution.create({
  from: from,
  to: to,
  gas: '30000',
  feePayer: feePayer,
  input: caver.abi.encodeFunctionCall({
    name: 'store',
    type: 'function',
    inputs: [ { "internalType": "uint256", "name": "num", "type": "uint256" } ],
  }, [newValue.toString()]),
});
await fdExecutionTransaction.fillTransaction();
console.dir(fdExecutionTransaction );
const signedTransaction = await caver.rpc.klay.signTransaction(fdExecutionTransaction);


/** Console 로그
FeeDelegatedSmartContractExecution 
{
    "_type": "TxTypeFeeDelegatedSmartContractExecution",
    "_from": "0x49e8a1112b8402d45a133e61f25a8c19e96b8267",
    "_gas": "0x7530",
    "_signatures": [
        {
            "_v": "0x01",
            "_r": "0x",
            "_s": "0x"
        }
    ],
    "_feePayer": "0x2214bac5f641b8a1c8a1942700de64474212b5d1",
    "_feePayerSignatures": [
        {
            "_v": "0x01",
            "_r": "0x",
            "_s": "0x"
        }
    ],
    "_to": "0x7e7e54de0d34009492bc5cba3f9073198abea02a",
    "_value": "0x0",
    "_input": "0x6057361d0000000000000000000000000000000000000000000000000000000000002bd6",
    "_chainId": "0x3e9",
    "_gasPrice": "0x5d21dba00",
    "_nonce": "0x11",
    "typeInt": 49
}

Kaikas - RPC Error: Error: Only fee delegated transaction can be signed with signTransaction request. Use 'sendTransaction' to sign transaction and send to network.