공부하기 위해서 번역하는 글입니다.
원문 : https://medium.com/@codetractio/inside-an-ethereum-transaction-fa94ffca912f
이더리움은 거래를 기반으로 하는 상태 머신이라 생각 할 수 있습니다.
거래(transactions)는 상태(state)를 바꿀 수 있고, 상태는 상호작용을 추적합니다.
여기서 우리는 거래의 구성요소를 상위수준에서 조사하고, 대부분의 이해할 수 없는 hex값이 어떻게 결정되는지 설명합니다.
이 튜토리얼에서는 nodejs를 사용할 것입니다. 따라서 tx.js 파일을 만들고, 의존성을 요구하는 것으로 시작합니다.
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider('https://ropsten.infura.io/'));
var util = require('ethereumjs-util');
var tx = require('ethereumjs-tx');
첫번째로 개인키와 함께 시작합니다. *private key
이더리움은 공개키 암호방식을 사용합니다. *public key cryptography
보다 구체적으로 말해서, 타원 곡선 전자 서명 알고리즘(secp256k1을 활용한 ECDSA)이 사용되었습니다.
*Elliptic Curve Digital Signature Algorithm
개인 키는 일부 제약사항을 제외하고, 임의의 256비트 데이터입니다.
예를 들면..
var privateKey = '0xc0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de';
이에 대응하는 공개 키를 도출 하려면
var publicKey = util.bufferToHex(util.privateToPublic(privateKey));
공개 키를 출력하면 다음과 같은 결과를 얻게 됩니다.
0x4643bb6b393ac20a6175c713175734a72517c63d6f73a3ca90a15356f2e967da03d16431441c61ac69aeabb7937d333829d9da50431ff6af38536aa262497b27
이 개인 키와 관련된 Ethereum 주소는 공개 키의 SHA3-256 (Keccak) 해시의 마지막 160 비트입니다.
var address = '0x' + util.bufferToHex(util.sha3(publicKey)).slice(26);
//0x53ae893e4b22d707943299a8d0c844df0e3d5557
보시다시피, 여러개의 개인 키가 동일한 주소를 가질 수 있습니다. Ethereum 계정은 각 주소마다 연결되어 있으며 각 주소는 다음과 같습니다.
nonce : 0으로 시작하는 외부 트랙잭션의 갯수
balance : 계정에 있는 이더의 양
storageRoot : 계정의 스토리지와 관련된 해시
codeHash : 계정을 관리하는 코드의 해시. 비어 있으면 계정은 비공개 키를 사용하여 액세스 할 수있는 일반 계정입니다. 그렇지 않으면 상호 작용에 코드가 적용되는 스마트 계약입니다.
다음으로 거래(transaction)를 살펴보면 6 개의 입력 필드가 있습니다.
nonce : 0으로 시작하는 외부 트랙잭션의 갯수
gasPrice : 거래가 발생하는 이더의 양을 결정하는 가격
gasLimit : 거래를 처리하는 데 허용되는 최대 가스
to : 트랜잭션이 전송되는 계정. 비어 있으면 트랜잭션이 계약을 생성
value : 보낼 이더의 양
data : 임의의 메세지 or 계약에 대한 함수 호출 or 계약을 생성하는 코드
1000 wei의 ether를 보내고 0xc0de 메시지를 남기는 트랜잭션은 다음과 같이 구성 될 수 있습니다.
var rawTx = {
nonce: web3.toHex(0),
gasPrice: web3.toHex(20000000000),
gasLimit: web3.toHex(100000),
to: '0x687422eEA2cB73B5d3e242bA5456b782919AFc85',
value: web3.toHex(1000),
data: '0xc0de'
};
보낸 사람 주소가 지정되지 않았으므로,
개인 키로 사인한 후에 서명으로부터 파생됩니다.
거래에 사인하려면..
var p = new Buffer('c0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de', 'hex');
var transaction = new tx(rawTx);
transaction.sign(p);
그런 다음 트랜잭션을 네트워크로 보내고 256 비트 트랜잭션 ID로 추적합니다. 이 트랜잭션은 Etherscan에서 볼 수 있습니다. 트랜잭션 ID는 트랜잭션의 해시입니다.
console.log(util.bufferToHex(transaction.hash(true)));
//0x8b69a0ca303305a92d8d028704d65e4942b7ccc9a99917c8c9e940c9d57a9662
다음으로, 함수 호출을 위해 무엇이 'data'를 구성하는지 살펴볼 것입니다.
예를 들어, 계약에 대한 이 거래의 데이터는..
console.log(web3.eth.getTransaction('0xaf4a217f6cc6f8c79530203372f3fbec160da83d1abe048625a390ba1705dd57').input);
//0xa9059cbb0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e000000000000000000000000000000000000000000000000d02ab486cedbffff
어떤 기능이 호출되는지 알기 위해서는 계약의 기능을 미리 알고 해시 테이블을 작성해야합니다.
첫 번째 32 비트 'a9059cbb'는 해시함수의 첫 번째 32 비트입니다.
이 경우 함수는 다음과 같습니다.
transfer(address _to, uint256 _value)
그리고 그 해시는...
console.log(web3.sha3('transfer(address,uint256)'));
//0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b
각 인수에 256 비트가옵니다.이 경우 주소는 다음과 같습니다.
0x0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e
그리고, unsigned integer는 다음과 같습니다.
0x000000000000000000000000000000000000000000000000d02ab486cedbffff
다음으로 위에서 설명한대로 'to'필드를 생략하면 계약이 생성됩니다.
그렇다면, 계약의 주소는 어떻게 결정될까요?
예를 들어, 이 거래는...
console.log(web3.eth.getTransactionReceipt('0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5').contractAddress);
//0x950041c1599529a9f64cf2be59ffb86072f00111
계약 주소는 발신자 주소의 마지막 160비트 해시이며, nonce는 미리 결정될 수 있습니다. 이 거래를 위해 발신자와 nonce는 다음과 같이 확인할 수 있습니다.
var contractTx = web3.eth.getTransaction('0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5');
console.log(contractTx.from);
//0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f
console.log(contractTx.nonce);
//0
따라서 계약주소는 다음과 같습니다.
console.log('0x' + util.bufferToHex(util.rlphash(['0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f', 0])).slice(26));
//0x950041c1599529a9f64cf2be59ffb86072f00111
이제 우리는이 16 진수에 대해 조금 더 알게되었습니다!
Ethereum과 smart contracts는 많은 산업을 혼란에 빠뜨릴 큰 잠재력을 가지고 있습니다. 온라인 자료가 많이 있으며, 아래에서 Ethereum 탐구 여행을 계속할 수 있습니다!
Ethereum main site https://www.ethereum.org/
Mist, one of Ethereum’s client https://github.com/ethereum/mist/releases
Solidity http://solidity.readthedocs.io/en/latest/
Web3 api https://github.com/ethereum/wiki/wiki/JavaScript-API
Community discussions https://www.reddit.com/r/ethereum/
If you have any issues regarding this article, you can raise it at our Github under the nightlyHacks repo.
와우. atomrigs 님 블로그에 있는 추천 글을 보고, 무작정 읽어 보며 글을 따라 갔는데... 역시 쉽지 않습니다.