Service-chain에서 머클루트 값 계산

안녕하세요 서비스체인 노드를 구성하여 구동 중에 블록에 포함되는 transactionRoot값을 계산하려고 하고 있습니다.

위에서 해주신 답변을 참조해서 진행하고 있는데요


일단 사진과 같이 deriveshaimpl 항목값을 2로 governance.vote 를 통해 설정한뒤

여기서 나와 있는 코드를 참고해서 똑같이 작동하도록 아래와 같이 js 코드를 작성했습니다.

const EthereumjsUtil = require('ethereumjs-util');

class DeriveShaConcat {
    deriveSha(list) {
        let concatenatedData = Buffer.from([]);

        for (let i = 0; i < list.length; i++) {
            const encodedItem = EthereumjsUtil.rlp.encode(list[i]);
            concatenatedData = Buffer.concat([concatenatedData, encodedItem]);
        }

        const hash = EthereumjsUtil.keccak256(concatenatedData);
        return '0x' + hash.toString('hex');
    }
}

// Usage example:
const list = ["0x250919e44166ddeb23418f75c5e88cdc9ce86396e3c8048c1e4944890b8de29f"];
const deriveShaConcat = new DeriveShaConcat();
const resultHash = deriveShaConcat.deriveSha(list);
console.log('Derived Hash:', resultHash);

그리고 트랜잭션을 발생시킨 뒤 블록에 포함된 트랜잭션 해시를 사용해서 테스트를 해보았는데요. 하지만 아래와 같이 제가 작성한 js 코드에서 나온 결과값과 블록에 저장된 transactionsRoot값이 다르게 나왔습니다. 혹시 위 코드에서 어떤 부분이 실제 계산하는 방법과 다른지 알 수 있을까요?

안녕하세요,

트랜잭션의 해시가아닌, 트랜잭션 구조체의 RLP를 계산해야 합니다.(https://github.com/klaytn/klaytn/blob/dev/blockchain/types/transaction.go#L847). Klaytn go package를 사용해서 Go 언어로 작성하시면 해당함수를 이용할 수 있으므로 더 빨리 결과를 보실 수 있을 것 같습니다. 감사합니다.

1개의 좋아요

답변 감사드립니다!
그럼 혹시 klay console에서 트랜잭션 구조체에 들어가는 값들을 확인할 수 있는 명령어가 있나요??

klay.getTransaction로 확인할 수 있습니다.

@Lake 덕분에 어느정도 방향을 잡아가고 있습니다.
말씀하신대로 klaytn go package를 설치하여 문제를 해결해나가고 있는데, 제가 Go 언어를 다루는게 처음이라 어려움이 많습니다.

알려주신 GetRlp 함수에 인수로서 들어가는 Transactions라는 list에는 Transaction Type이 들어가는 것으로 알고 있습니다.

// GetRlp implements Rlpable and returns the i'th element of s in rlp.
func (s Transactions) GetRlp(i int) []byte {
	enc, _ := rlp.EncodeToBytes(s[i])
	return enc
}

Transaction Type에 대한 설명을 봤는데 어려움이 있어서 질문 드립니다.
아래는 하나의 transaction 예시 입니다.
{
blockHash: ‘0x457c3f4253ac3c1f3062889b9d5bb40103c700106455955acf60b93ec41afbe1’,
blockNumber: 3570712n,
from: ‘0x5d4b8de0f99f166fd6330c1e5e2cc39b8466e303’,
gas: 165566n,
gasPrice: 18n,
maxFeePerGas: 1000000036n,
maxPriorityFeePerGas: 1000000000n,
hash: ‘0x77c864ca44d105e529840a8edc95590fe5b6de5ee37d0054ba9711edad5eee77’,
input: ‘0xd204c45e0000000000000000000000005d4b8de0f99f166fd6330c1e5e2cc39b8466e3030000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005e68747470733a2f2f697066732e696f2f697066732f626166797265696664336b746e673674687463676433786d6f6d73776a37746733796a6a647574666b7932777362323676727572336d346b6761342f6d657461646174612e6a736f6e0000’,
nonce: 29981n,
to: ‘0x37d5103a711c8ddee980ce615dee541c5c8cbcf7’,
transactionIndex: 0n,
value: 0n,
type: 2n,
accessList: ,
chainId: 1004n,
v: 0n,
r: ‘0xff89b020c1e591382599da60053b35907aaf2f31cf11305b788dfbbe12bc14df’,
s: ‘0x195979939aa314e92862c5f098305814dd59e0aa900eaa1bc513f63c8adb67b5’,
data: ‘0xd204c45e0000000000000000000000005d4b8de0f99f166fd6330c1e5e2cc39b8466e3030000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005e68747470733a2f2f697066732e696f2f697066732f626166797265696664336b746e673674687463676433786d6f6d73776a37746733796a6a647574666b7932777362323676727572336d346b6761342f6d657461646174612e6a736f6e0000’
}

이 transaction 정보를 어떠한 방식으로 가공해야 Transactions list의 값으로 넣음으로서 GetRlp 함수를 실행시킬 수 있을까요?

많은 도움 받고 있습니다. 감사합니다

Transactions type은 GetRlp 함수의 receiver 입니다.

해당 함수와 동일한 파일에 Transaction type의 정의와 관련된 함수들이 정의되어 있습니다. 새로운 Transaction type 변수를 만들고 정의된 field에 값을 채울 수도 있고, NewTransaction 함수와 같이 몇몇 인자를 해당 type의 변수/포인터를 만드는 함수가 정의된 경우도 흔하게 찾아볼 수 있습니다.

Transaction type 변수를 만들고 Transactions type으로 변환해서 GetRlp 함수를 이용할 수도 있고, 또는 해당 함수의 내부 로직을 참고해서 직접 rlp.EncodeToBytes 함수를 호출하는 방법도 가능할 것 같습니다.