머클트리 알아보기

최현석·2021년 12월 29일
1

블록체인

목록 보기
2/5

필요한 모듈

  • crypto-js
  • merkletreejs

crypto-js/sha256 사용해보기

const cryptojs = require("crypto-js");
console.log(cryptojs.HmacSHA256("비밀번호", "sha256"));
// {
//     words: [
//       1277915998,
//       -1227407849,
//       -1577390688,
//       732648621,
//       -1577638131,
//       697868534,
//       -1386123058,
//       708010038
//     ],
//     sigBytes: 32
//   }

console.log(cryptojs.HmacSHA256("비밀번호", "sha256").toString()); //4c2b735eb6d73e17a1faeda02bab54ada1f7270d2998a0f6ad6170ce2a336036

모듈 불러오기 및 선언

// test_merkleTree.js
const {MerkleTree} = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')

Nodejs에서는 merkletreejs와 SHA256을 암호화해주는 crypto-js 모듈을 지원해주고 있습니다

const leaves = ["a", "b", "c"].map((x) => SHA256(x));
console.log(leaves);

보기 쉽게 toString() 함수를 사용해봅니다

const leaves = ["a", "b", "c"].map((x) => SHA256(x));
console.log(leaves.toString());
//ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb,3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d,2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6

MerkleTree 선언하기

아래 그림의 예시와 같이 tree 변수에 새 MerkleTree를 담아 봅시다

const tree = new MerkleTree(leaves, SHA256);

매개변수로 leaves에는 배열, hashFn? 에는 변경하고자 하는 해시함수를 담을 수 있습니다.

  • 해당 tree를 콘솔로 찍어봅시다!

아래 그림과 같은 트리형태를 내보여주고 있습니다.

해당 트리의 Root값만 가져오고 싶으면 getRoot() 함수를 사용하면 됩니다.

const root = tree.getRoot().toString("hex");
console.log(root); //7075152d03a5cd92104887b476862778ec0c87be5c2fa1c0a90f87c49fad6eff

값 verify 해보기

  • 그럼 leaf에 a 값이 있는지 확인해 보겠습니다.
  • 먼저 MerkleTree에서 getProof() 함수를 사용해서 Proof값을 가져오겠습니다
  • getProof()는 객체안에 왼쪽 또는 오른쪽이라는 position과 Buffer 타입의 data를 배열로 반환해줍니다

const leaf = SHA256("a");
const proof = tree.getProof(leaf);

해당 proof와 leaf, 머클트리의 root를 가지고 입력한 leaf의 값이 맞는지 확인합니다.

console.log(tree.verify(proof, leaf, root)); // true

해당 값이 맞으면 true를 반환해줍니다.

  • 제대로 되지 않은 값을 입력해 보겠습니다.
const badLeaves = ["a", "x", "c"].map((x) => SHA256(x));
const badTree = new MerkleTree(badLeaves, SHA256);
const badRoot = badTree.getRoot().toString("hex");
const badLeaf = SHA256("b");
const badProof = badTree.getProof(badLeaf);
console.log(tree.verify(badProof, badLeaf, badRoot)); // false

값을 비교해보고 맞지 않으므로 false를 반환합니다.

전체 코드 ( 공부 )

// test_merkleTree.js
const {MerkleTree} = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')

console.log(SHA256('a').toString()) // ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb

const testSet = ['a', 'b', 'c', 'd', 'e']
const testArray = testSet.map((v) => SHA256(v).toString())

console.log(testArray) // testSet SHA256 해시값 변환한 것들 testArray에 담았음

const testMerkleTree = new MerkleTree(testArray, SHA256)
console.log(testMerkleTree) // testArray를 MerkleTree로 생성 트리로 값 반환

const merkleRoot = testMerkleTree.getRoot()
console.log(merkleRoot.toString('hex')) // 해당 트리의 hash 값 d71f8983ad4ee170f8129f1ebcdd7440be7798d8e1c80420bf11f1eced610dba

const trueTestValue = 'a'
const trueLeaf = SHA256(trueTestValue)
const trueProof = testMerkleTree.getProof(trueLeaf)
console.log(trueProof) // proof리턴 ( position, Buffer data )

const trueResult = testMerkleTree.verify(trueProof, trueLeaf, merkleRoot)
console.log(trueResult) // true

const falseTestValue = 'z'
const falseLeaf = SHA256(falseTestValue)
const falseProof = testMerkleTree.getProof(falseLeaf)
console.log(falseProof) // testMerkleTree에서 해당 Proof 가져올 수 없음 빈 배열 반환[]
profile
개발자 꿈나무 https://github.com/Tozinoo

0개의 댓글