import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"nft-common/cryptor"
"testing"
mt "github.com/txaty/go-merkletree"
)
var leaves = []string{
"0x6EFd53BA1f3DD573EAc80B82b4B6266F6dEFA4bD",
"0x0F9C1bcC4BA8a85194ABe5B14565eB43CDEe2ed7",
"0xf852007A9Cb2771a34DAF6fc5d2AD430a638beae",
"0x2bF965771801faC320eBC067AF5aEC1a0AB62fA2",
"0x560950f740916F1c6D0750EC1b7ad2bd98691BC7",
"0x3535d10Fc0E85fDBC810bF828F02C9BcB7C2EBA8",
"0x680A72cB90322537c664Dedd5F6A1423eD892F0F",
"0xe583DC38863aB4b5A94da77A6628e2119eaD4B18",
"0x892e7c8C5E716e17891ABf9395a0de1f2fc84786",
}
func testLeafHashFunc(address common.Address) ([]byte, error) {
codeBytes, err := cryptor.AbiCoder([]string{"address"}, []interface{}{address})
if err != nil {
return nil, errors.Wrap(err, "AbiCoder")
}
hash := crypto.Keccak256Hash(codeBytes)
return hash.Bytes(), nil
}
func TestLeafHash(t *testing.T) {
for _, leaf := range leaves {
hashBytes, err := testLeafHashFunc(common.HexToAddress(leaf))
require.NoError(t, err)
t.Log(common.BytesToHash(hashBytes).Hex())
}
}
func LeafHashFunc(addressByte []byte) ([]byte, error) {
address := common.BytesToAddress(addressByte)
codeBytes, err := cryptor.AbiCoder([]string{"address"}, []interface{}{address})
if err != nil {
return nil, errors.Wrap(err, "AbiCoder")
}
hash := crypto.Keccak256Hash(codeBytes)
return hash.Bytes(), nil
}
type Leave string
func (l Leave) Serialize() ([]byte, error) {
return hexutil.Decode(string(l))
}
func TestOpenzeppelinSortMerkleTree(t *testing.T) {
config := &mt.Config{
HashFunc: LeafHashFunc,
NumRoutines: 0,
Mode: mt.ModeProofGenAndTreeBuild,
RunInParallel: false,
SortSiblingPairs: true,
DisableLeafHashing: false,
}
dataBlocks := make([]mt.DataBlock, 0, len(leaves))
for _, leaf := range leaves {
dataBlocks = append(dataBlocks, Leave(leaf))
}
merkleTree, err := mt.New(config, dataBlocks)
require.NoError(t, err)
root := hexutil.Encode(merkleTree.Root)
t.Log(root)
proofs := merkleTree.Proofs
t.Log(ProofsStrings(proofs))
node := Leave("0x6EFd53BA1f3DD573EAc80B82b4B6266F6dEFA4bD")
proof, err := merkleTree.Proof(node)
require.NoError(t, err)
t.Log(ProofStrings(proof))
verify, err := merkleTree.Verify(node, proof)
require.NoError(t, err)
require.True(t, verify)
}
func ProofStrings(p *mt.Proof) []string {
res := make([]string, 0)
for _, sibling := range p.Siblings {
proof := hexutil.Encode(sibling)
res = append(res, proof)
}
return res
}
func ProofsStrings(p []*mt.Proof) [][]string {
res := make([][]string, 0)
for _, proof := range p {
pp := make([]string, 0)
for _, sibling := range proof.Siblings {
pHex := hexutil.Encode(sibling)
pp = append(pp, pHex)
}
res = append(res, pp)
}
return res
}