์๋
ํ์ธ์,
caver-js ์ด์ฉํด์ raw transaction data ์์ฑ ํ ์คํ๋ผ์ธ ์๋ช
์ ํ๊ณ ์ถ์๋ฐ docs ์ ๋์จ ์ค๋ช
์ ๋ฐ๋ผ valueTransfer transaction ์ hash ํ๊ณ signature ์์ฑ ํ ์ ์กํ๋ ๊ณผ์ ์ด ์ ๋์ง ์์ ์ง๋ฌธ ์ฌ๋ฆฝ๋๋ค.
์๋๋ ์ ๊ฐ ํ ์คํธํ๊ณ ์๋ ์ฝ๋ ์ ๋ฌธ์ ๋๋ค.
const Caver = require('caver-js')
const { numberToHex } = require('caver-js/packages/caver-utils')
const Hash = require('eth-lib/lib/hash')
const RLP = require('eth-lib/lib/rlp')
const caver = new Caver('https://klaytn-baobab.blockpi.network/v1/rpc/public') // Boabob testnet
async function main() {
x = numberToHex('94615564755326464618865695935486540640291201192934633168530032620020725956813')
y = numberToHex('23139757045517286211017265994855088265935370642351252538574909408042960511313')
pub = x + y.slice(2)
sender = caver.utils.publicKeyToAddress(pub) // test sender
console.log("sender address:", sender)
to_address = '0x2bb947ba1ae588e043e0f7ee166748766b4d605b' // baobab wallet
chainId = 1001 // baobob
const tx = caver.transaction.valueTransfer.create({
// type: '0x08', // 'TxTypeValueTransfer'
nonce: 0,
gasPrice: '0x5d21dba00',
gas: '0x0a',
to: to_address,
value: caver.utils.toPeb(10, 'KLAY'),
from: sender, // '0x14E8d03a51F2b77a06cf4AA6600D608aE8361C27',
chainId: numberToHex(chainId),
})
const encoded = tx.getCommonRLPEncodingForSignature()
const sigHash = Hash.keccak256(encoded)
// const sigHash = Hash.keccak256("\x19Klaytn Signed Message:\n" + encoded.length + encoded)
console.log("msg hash:",sigHash) // msg
/* offline signing - make signature(v, r, s)*/
v = numberToHex(chainId*2 + 35 + 0)
r = numberToHex('15889454641529804590699241749915670778420230958983654827606059186073800710978');
s = numberToHex('39389016946565651388873849274764251362165017942396879121292298320138309110729');
// tx.appendSignatures([v, r, s])
tx.signatures = [v, r, s]
txHashRLP = tx.getRLPEncoding()
pubkey = tx.recoverPublicKeys()
console.log("recovered address:",caver.utils.publicKeyToAddress(pubkey))
// const receipt = await caver.klay.sendSignedTransaction(txHashRLP)
const receipt = await caver.rpc.klay.sendRawTransaction(txHashRLP)
console.log(receipt)
}
main();
- ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ฑํ x, y ๊ฐ์ผ๋ก create sender address
- create valueTransfer transaction object
-
- RLP encoding-> Hash ํ์ฌ Sign ํ msg ์์ฑ
- signature data ์ฝ์
- recovered address ํ์ธ
- ์ ์ก
์ ๊ณผ์ ์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ด๋๋ฆฌ์ ํธ๋์ญ์ ์ ์์ฑํ๊ณ ์๋ช ํ๋ ๊ฒ์๋ ์ฑ๊ณตํ์์ต๋๋ค.
ํ์ง๋ง ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด, ์๋์ ๊ฐ์ด ๋ณต๊ตฌ์ ์ฌ์ฉํ๋ ค๋ public key ๊ฐ ์๋ชป๋๋ค๋ ์๋ฌ๊ฐ ๋์ต๋๋ค.
(node:34523) UnhandledPromiseRejectionWarning: Error: Invalid public key: 0x1d53faa428eabd2db08bbe3c3256b6a00ea4246bdbfdde6cf3f4fe65a3b613cf475c7f276b75f2947220ee1cb2c8fff00a835e4028502e735c0c056847e7ae8b
at Object.publicKeyToAddress (/Users/hoodie/klaytn/caver-js/packages/caver-utils/src/utils.js:1484:59)
at main (/Users/hoodie/klaytn/tx.js:49:50)
at Object.<anonymous> (/Users/hoodie/klaytn/tx.js:55:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47
(Use `node --trace-warnings ...` to show where the warning was created)
....
์ฃผ์ ๋ณต๊ตฌ ์ฝ๋๋ฅผ ์ฃผ์์ฒ๋ฆฌํ๊ณ ์คํํ๋ฉด signature ๊ฐ ์๋ชป๋๋ค๋ ์๋ฌ๊ฐ ๋์ต๋๋ค.
UnhandledPromiseRejectionWarning: Error: Returned error: invalid transaction v, r, s values of the sender
...
3๋ฒ ๊ณผ์ ์ด ์ด๋๋ฆฌ์์ ์ ์กํ ๋์๋ ๋ฌธ์ ๊ฐ ๋๋ ๋ถ๋ถ์ด๊ณ , Klaytn docs ์ RLP Encoding for Signature ์ ์ ํ์๋ ์๋ ์๋์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์ง๋ง ์ ์ ํ ๊ตฌํ์ด ๋ ๊ฒ์ธ์ง ๊ฒ์ฆํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ sign ์ msg๋ฅผ ์ ์ ํ ์ฌ์ฉํ์ง ๋ชปํ๊ณ ์์ง ์๋ ์๊ฐํฉ๋๋ค. ๋ฌผ๋ก ๋ค๋ฅธ ์์ธ์ด ์ถ๊ฐ๋ก ์์ ์๋ ์์ต๋๋ค๋ง ๋ฐ๊ฒฌํ์ง ๋ชปํ๊ณ ์์ด์ ๋ค์ํ ์๊ฐ์์ ์ ๋ฌธ๊ฐ๋ถ๋ค์ ๋์์ ์์ฒญ๋๋ฆฝ๋๋ค.
SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from]), chainid, 0, 0])
SigHash = keccak256(SigRLP)
Signature = sign(SigHash, <private key>)
์ฝ๋๊ฐ ์๋ชป๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ์ฌ๋ฐ๋ฅด๊ฒ ์์ ํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์ถ์ต๋๋ค.
์๊ฐ ๋ด์ด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค.
๋ง๋ถ์ด์๋ฉด ์๋ช ์๋ Alice TSS ๋ผ์ด๋ธ๋ฌ๋ฆฌ(ECDSA)๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. private key๋ฅผ ๋ค๋ฃฐ ์ ์์ด์ public key ๋ก ์ง์ ์ฃผ์๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๋ ค๊ณ ํ์ต๋๋ค.