Fee delegation에 대한 문의

안녕하세요. fee delegation에 대하여 아래와 같이 문의 드립니다.

  1. caver-js로 구현된 코드에 fee delegation 적용.

    // 현재 코드.
    const walletInstance = caver.klay.accounts.privateKeyToAccount(privKey)
    caver.klay.accounts.wallet.add(walletInstance)
    let contract = new caver.klay.Contract(contractABI, tokenAddress);
    contract.methods.transferFrom(fromAddress, toAddress, value).send(
    {
    from: walletInstance.address,
    gas: ‘100000’
    }
    ).once(“transactionHash”, function (hash) {
    // 이하 생략.

    저는 간략하게 transaction을 위와 같이 처리하고 있는데, transaction 처리 방식을 변경하지 않고, 위 코드에 fee delegation을 적용하는 예시의 공유를 부탁드립니다. (제가 개발 가이드에서는 찾지 못했고, 시간을 아끼고자 합니다.)

  2. 만약, 동시에 서로 다른 복수개(예를 들어 5개)의 ERC20 기반 token의 transferFrom transaction 요청에동일한 fee payer address의 이용이 가능할는지요?
    : 지난 주에 fee delegation 계정 등록을 요청하고, fee payer address를 받았는데
    저희가 관리하는 복수개의 Token의 전송에 적용을 하려고 하니 이슈가 될 것 같아서요.
    fee payer의 nonce 또는 original gas fee payer(fee payer address와 matching되는 원 가스비 지출계정)의 nonce 문제가 있지 않을까 합니다…

그럼 답변 부탁드립니다. (_ _)

안녕하세요 먼저 질문 올려주셔서 감사합니다.

  1. 현재 caver.klay.contract. caver.klay.kip7, caver.klay.kip17 모두 수수료 대납은 지원되지 않습니다. 따라서 스마트 컨트랙트를 호출할 때에 수수료를 대납하고 싶으신 경우, 별도로 트랜잭션을 생성해서 서명하고 전송해 주셔야 합니다.

아래에 간단한 예시를 작성했습니다.
Prepare for testing 부분은 테스트를 위한 준비 과정이므로, 생략 하셔도 되고 그 이후부터 보시면 됩니다.

간략하게 설명드리면 아래의 플로우로 진행됩니다.
-FEE_DELEGATED_SMART_CONTRACT_EXECUTION 타입의 트랜잭션을 생성
이 때에 data에는 encode된 function call이 들어가야 함. (참고로 올려주신 예제에서 transferFrom을 사용하고 계셔서, KIP7의 transferFrom을 기준으로 작성되었습니다.) encodeFunctionCall을 하는 방법은 https://docs.klaytn.com/bapp/sdk/caver-js/v1.4.1/api-references/caver.klay.abi#encodefunctioncall 이 문서를 참고해 주세요.
-트랜잭션 sender 서명
-트랜잭션 fee payer 서명
-Klaytn network 전송

const sender = caver.klay.accounts.wallet.add('0x{private key}')
const feePayer = caver.klay.accounts.wallet.add('0x{private key}')
const to = caver.klay.accounts.create() // to account 

// Prepare for testing
const kip7 = await caver.klay.KIP7.deploy(
    {
        name: 'Jasmine',
        symbol: 'JAS',
        decimals: 18,
        initialSupply: '1000000000000000000',
    },
    sender.address
)
const kip7TokenAddress = kip7.options.address

const spender = caver.klay.accounts.wallet.add('0x{private key}')

const vt = {
    type: 'VALUE_TRANSFER',
    from: sender.address,
    to: spender.address,
    value: caver.utils.toPeb(10, 'KLAY'),
    gas: 30000,
}
const signed = await caver.klay.accounts.signTransaction(vt)
const receipt = await caver.klay.sendSignedTransaction(signed)
console.log(`Token transfer to test receipt ==========> `)
console.log(receipt)

const approved = await kip7.approve(spender.address, 100000, { from: sender.address })
console.log(`\nToken approve to test receipt ==========> `)
console.log(approved)
// Prepare for testing is done


// Create FEE_DELEGATED_SMART_CONTRACT_EXECUTION
const execution = {
    type: 'FEE_DELEGATED_SMART_CONTRACT_EXECUTION',
    from: spender.address,
    to: kip7TokenAddress,
    data: caver.klay.abi.encodeFunctionCall(
        {
            constant: false,
            inputs: [{ name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }],
            name: 'transferFrom',
            outputs: [{ name: '', type: 'bool' }],
            payable: false,
            stateMutability: 'nonpayable',
            type: 'function',
        },
        [sender.address, to.address, 10]
    ),
    gas: 100000,
}

const senderSigned = await caver.klay.accounts.signTransaction(execution)
console.log(`\nSender signing result ==========> `)
console.log(senderSigned)
const feePayerSigned = await caver.klay.accounts.feePayerSignTransaction(senderSigned.rawTransaction, feePayer.address)
console.log(`\nFee payer signing result ==========> `)
console.log(feePayerSigned)

// Send signed transaction to the Klaytn network
const receiptForTransferFrom = await caver.klay.sendSignedTransaction(feePayerSigned)
console.log(`\nTransferFrom receipt ==========> `)
console.log(receiptForTransferFrom)
  1. fee payer 의 nonce 는 따로 트랜잭션에 저장되는 정보가 아니기 때문에 동시에 서로 다른 복수 개의 트랜잭션에 하나의 fee payer 주소로 이용이 가능할 것 같습니다. 혹시 해보시고 문제 생기시면 말씀해 주세요.

감사합니다 :slight_smile:

보내주신 답글을 참고하여 baobab에서 정상적으로 fee delegation을 처리하였습니다.
감사합니다.(_ _)

연결하여, 질문을 드립니다.

얼마 전에 fee delegation payer address에 대한 메일을 받고, 제가 가진 account의 public key를 회신하여,
fee delegation으로만 사용가능한 fee payer address를 받았습니다. (scope를 통해 500 KLAY가 들어있는 것을 확인하였습니다.)

제가 가진 account의 keystore 파일의 address 부분을 대납 계정 address로 대체하고
이를 이용하여 fee delegation을 진행하는 예시(klay transfer 예시)도 받았습니다.

그런데 예시의 형태가 @Jamie 님께서 공유해 주신, KIP-7의 transferFrom을 처리하는 형태와는 좀 달라서 아직 완전하게 해결을 못하고 있습니다.

제가 Bapp 개발에 시간이 촉박하기에, 혹시 상기와 같이 fee payer address 및 keystore file을 이용하여 KIP-7의 transferFrom을 처리하는 예제가 있다면 공유를 부탁드립니다.

항상 감사합니다.

네 안녕하세요 !

const keystore = fs.readFileSync('./keystore.json', 'utf8')

// Decrypt keystore
const feePayerAccount = caver.klay.accounts.decrypt(keystore, password)
console.log(feePayerAccount)

caver.klay.accounts.wallet.add(feePayerAccount)

이렇게 keystore를 로드하시고 위에 답변드린 코드대로 진행하시면 됩니다.

1개의 좋아요

감사합니다. (_ _);

맨 처음 공유해주신 것에 방금 추가해 주신 내용을 덧붙이니 잘 처리가 됩니다.

제가 caver-js를 1.4.1에서, caver-js 1.5.0으로 업데이트하면서 function을 좀 헷갈렸나 봅니다.
전달받은 예제에 나온 keyring에 대해서도 생소했고요.

다시 한번 감사드립니다.

2개의 좋아요