don't stop believing

Ether 송금 과 수수료 확인 (on Local TestNet) 본문

Ethereum

Ether 송금 과 수수료 확인 (on Local TestNet)

Tongchun 2018. 8. 24. 15:31


채굴하기 (on Local TestNet)


Ether를 생성했으니 eth.accounts[0]에서 eth.accounts[1]로 송금해 봅시다.

송금은 sendTransaction 명령으로 수행합니다. from에 보내는 주소, to에 받는 주소, value에 송금액을 wei 단위로 적습니다.

> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(10,"ether")})
Error: account is locked
    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at :1:1


송금을 실행하면 에러가 발생합니다. 트랜잭션의 발행은 유료이며 from에 지정된 주소에서 수수료가 발생합니다. 따라서 잘못된 실행을 방지하기 위해 언제나 잠금 상태이며, 사용할 때 잠금을 해재(Unlock)해야 합니다.

personal.unlockAccount 명령으로 계정 잠금을 해제할 수 있습니다.

명령을 실행하면 계정의 암호를 물어보는데 설정한 암호를 입력하면 잠시 후 true를 반환하며 계정 감금이 해제 됩니다.


비밀번호를 잊지않기 위해 기롭해 둡니다.

eth.accounts[0]    ngle1234

eth.accounts[1]    tongchun1234

eth.accounts[2]    macaron1234


> personal.unlockAccount(eth.accounts[0])
Unlock account 0x26a43bc3dcef48f91b77df47dd353d9f34c163c4
Passphrase: 
true

personal.unlockAccount 명령은 다음과 같이 인수에 암호를 입력할 수도 있습니다.

> personal.unlockAccount(eth.accounts[0], "ngle1234")
true

계정 잠금 해제 유효 시간은 기본적으로 300초입니다. 이 시간을 연장하는 인수도 추가로 입력할 수 있습니다.

(초 단위)로 입력하며 0을 입력할 경우 Geth 프로세스가 종료되기 전까지 계정 잠금 해제 상태를 유지할 수 있습니다.

> personal.unlockAccount(eth.accounts[0], "ngle1234", 0)
true

계정 잠금을 해제했다면 다시 한번 sendTransaction 명령을 실행해 봅니다.

> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(10,"ether")})
"0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a"

정상적으로 송금이 되었는지 확인해 봅시다.

> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
605
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
0

잔고는 변함이 없습니다.

sendTransaction으로 트랜잭션을 발생해도 처리가 실행되지 않습니다. 블록체인에서는 블록 안에 그 트랜잭션이 포함될 때 드랜잭션의 내용이 실행됩니다. 트랜잭션 상태를 확인해 보겠습니다.

sendTransaction 명령 실행 후 리턴되는 Transaction ID를 eth.getTransaction 명령으로 실행해 보겠습니다.

> eth.getTransaction("0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a")
{
  blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  blockNumber: null,
  from: "0x26a43bc3dcef48f91b77df47dd353d9f34c163c4",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a",
  input: "0x",
  nonce: 0,
  r: "0x3b996f93fdb5070c92385ee8b71affd311a5cd2cd78359df0d140f5bceaeaf26",
  s: "0x1dd796df46c678460d316e02a08b3dd95695a296fa46e7970e5d811c528c0618",
  to: "0x6a6ea6d5128554638b138a5331529989fcde4271",
  transactionIndex: 0,
  v: "0x7e",
  value: 10000000000000000000
}

트랜잭션 정보에서 blockNumber가 null로 되어있습니다. null은 블록에 포함되지 않은상태(미처리, 계류 중)를 표시합니다.

eth.pendingTransactions 명령으로 계류 중인 트랜잭션을 확인할 수 있습니다.

> eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0x26a43bc3dcef48f91b77df47dd353d9f34c163c4",
    gas: 90000,
    gasPrice: 18000000000,
    hash: "0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a",
    input: "0x",
    nonce: 0,
    r: "0x3b996f93fdb5070c92385ee8b71affd311a5cd2cd78359df0d140f5bceaeaf26",
    s: "0x1dd796df46c678460d316e02a08b3dd95695a296fa46e7970e5d811c528c0618",
    to: "0x6a6ea6d5128554638b138a5331529989fcde4271",
    transactionIndex: 0,
    v: "0x7e",
    value: 10000000000000000000
}]

미처리된 트랜잭션을 처리하기 위해 채굴을 시작해 블록을 생성하겠습니다.

> miner.start(1)
null

잠시 기다린 뒤 다시 eth.pendingTransaction을 실행해보면 미처리 트랜잭션 내용이 사라진 것을 볼 수 있습니다.

채굴을 중지하고 블록 수를 확인해 보겠습니다.

> eth.pendingTransactions
[]
> miner.stop()
true
> eth.blockNumber
139

eth.getTransaction 명령으로 트랜잭션을 다시 확인해보면 null이었던 blockNumber에 숫자가 할당된 것을 확인할 수 있습니다.

> eth.getTransaction("0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a")
{
  blockHash: "0x18734b3b540805e3a7d3717550b24b4c9f682481b34ec025e2a4d6c0cc55ed9e",
  blockNumber: 122,
  from: "0x26a43bc3dcef48f91b77df47dd353d9f34c163c4",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a",
  input: "0x",
  nonce: 0,
  r: "0x3b996f93fdb5070c92385ee8b71affd311a5cd2cd78359df0d140f5bceaeaf26",
  s: "0x1dd796df46c678460d316e02a08b3dd95695a296fa46e7970e5d811c528c0618",
  to: "0x6a6ea6d5128554638b138a5331529989fcde4271",
  transactionIndex: 0,
  v: "0x7e",
  value: 10000000000000000000
}

122번 블록에 트랜잭션이 포함되어 있습니다.

이번엔 eth.getBlock 명령으로 블록을 확인해 보겠습니다. transaction 항목에 앞의 트랜잭션 ID 값이 표시되는 것을 확인 할 수 있습니다.

> eth.getBlock(122)
{
  difficulty: 132154,
  extraData: "0xd88301080e846765746888676f312e31302e31856c696e7578",
  gasLimit: 1906173853,
  gasUsed: 21000,
  hash: "0x18734b3b540805e3a7d3717550b24b4c9f682481b34ec025e2a4d6c0cc55ed9e",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x26a43bc3dcef48f91b77df47dd353d9f34c163c4",
  mixHash: "0xbfda21b36987f89019243be16153f881f680a06bd14c200c8b88725e0a6558b6",
  nonce: "0x72c70990fe212ee9",
  number: 122,
  parentHash: "0x806167147ce0d0c74542592e357af313511e94f1ff464cb463f61c649556a145",
  receiptsRoot: "0x27a938e843e8d7045bbe4af96356731ecb55d8e9e005462f9901b3006451c0ba",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 651,
  stateRoot: "0x45685158c0958b11b303d1d3c36dc927d7ba11a7176637faead47c4e09ac6c6d",
  timestamp: 1535531250,
  totalDifficulty: 16463096,
  transactions: ["0x1fee683a5120c2aae5c0c7ed50c341e6a726cdff0c9984965a8b35789024471a"],
  transactionsRoot: "0x9de9fdd4c843d5c8034aa50864ed6317ff6dd80356a41387db93b8baf86ec5c1",
  uncles: []
}

무사히 송금이 완료되었으니 accounts[1]의 잔고를 확인해 보겠습니다.

> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
685
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
10

accounts[1]에 10 Ether가 입금된 것을 확인할 수 있습니다.

account[0]은 mining을 통해 Ether가 더 늘었습니다.


이제 accounts[1]에서 accounts[2]로 송금해 보겠습니다. 먼저 accounts[1]의 잠금을 해제하겠습니다.

> personal.unlockAccount(eth.accounts[1], "tongchun1234", 0)
true

sendTransaction 명령으로 account[1]에서 accounts[2]로 5 Ether를 송금합니다.

> eth.sendTransaction({from:eth.accounts[1], to:eth.accounts[2], value:web3.toWei(5,"ether")})
"0xa93bb6b69a71b2795588bbb8207470452d61a7584be5d2a97ccd996d2d4d01b9"

miner.start 명령으로 채굴을 시작하고 eth.pendingTransactins 명령으로 처리 여부를 학인하겠습니다. 처리가 되면 miner.stop을 해줍니다.

> miner.start(1)
null
> eth.pendingTransactions
[]
> miner.stop()
true
> eth.blockNumber
162

송금이 완료되었으니 잔고를 확인해 보겠습니다.

> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
800.000378
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
4.999622
> web3.fromWei(eth.getBalance(eth.accounts[2]), "ether")
5

Ether를 보내는 accounts[1]의 잔고가 5가 아니라 4.999622가 되었습니다. 0.000378이 차감되었습니다.

트랜잭션을 처리하기 위해서는 수수료(gas)가 필요합니다. Gas는 블록을 만들 때 주는 보상과 마찬가지로 채굴자(블록을 생성한 노드의 Etherbase)에게 지불됩니다. 트랜잭션 정보를 확인해 보겠습니다.

> eth.getTransaction("0xa93bb6b69a71b2795588bbb8207470452d61a7584be5d2a97ccd996d2d4d01b9")
{
  blockHash: "0x5694b4777b436c2e334fe91d3fdf668d6447c9a98719a8d551d93181ae9be9b8",
  blockNumber: 140,
  from: "0x6a6ea6d5128554638b138a5331529989fcde4271",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0xa93bb6b69a71b2795588bbb8207470452d61a7584be5d2a97ccd996d2d4d01b9",
  input: "0x",
  nonce: 0,
  r: "0x588c2fe630bb1c40bdceeaa21dde95c1b94f3ce77735894933b65b625ce6f6f9",
  s: "0x7fa0e28fd205e794c0ebdbdea6d771bffdf458a9d943e717d412d4cdf762405e",
  to: "0x7208e3ca69793ec72d6b08a3497edf8e447c5304",
  transactionIndex: 0,
  v: "0x7e",
  value: 5000000000000000000
}

여기서 확인할 부분은 gas와 gasPrice입니다. gasPrice는 1gas의 가격이며, 단위는 wei/gas 입니다. gas는 지불 가능한 최대 gas이며, 실제로 해당 트랜잭션을 처리하는 데 지불한 gas는 아닙니다. 


지불된 gas를 확인해 보겠습니다.

앞에서 확인한 0.000378 ether는 378,000,000,000,000 wei입니다.

지불한 수수료(wei) / gasPrice = 378,000,000,000,000 / 18,000,000,000 = 21,000 gas

실제 지불한 gas는 21,000 입니다. 트랜잭션에서 지정한 gas의 값 90,000 보다는 작은 것을 확인할 수 있습니다.


송금과 수수료 확인까지 알아봤습니다.


exit으로 geth를 종료합니다.


Comments