MerkleProof
简介链接:
https://yuhuajing.github.io/solidity-book/milestone_6/merkle-proof-validation.html
https://github.com/yuhuajing/solidity-book/tree/main/src/ContractsHub/merkle_tree_prove
merkleSecurity
为保证默克尔树的安全性,防止攻击者仅传递非叶子节点的数据跳过校验
叶子节点和验证节点的采用不用的 hash
校验:
叶子节点双 hash
待验证的叶子节点采用双 hash
的方式,区别叶子节点和验证节点的数据
func abiPackLeafHash(leafEncodings []string, values ...interface{}) ([]byte, error) {
data, err := AbiPack(leafEncodings, values...)
if err != nil {
return nil, err
}
hash, err := standardLeafHash(data)
return hash, err
}
func standardLeafHash(value []byte) ([]byte, error) {
k1, err := Keccak256(value)
if err != nil {
return nil, err
}
k2, err := Keccak256(k1)
return k2, err
}
单类型叶子节点
叶子节点仅采用单一数据类型,匹配的验证合约能够获取的数据有限
func MerkleOnlyOneArgOZ() {
leaf1 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
}
leaf2 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
}
leaf3 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
}
leaf4 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
}
leaf5 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
}
leaves := [][]interface{}{
leaf1,
leaf2,
leaf3,
leaf4,
leaf5,
}
tree, err := smt.Of(
leaves,
[]string{
smt.SOL_ADDRESS,
//smt.SOL_UINT256,
})
if err != nil {
fmt.Println("Of ERR", err)
}
root := hexutil.Encode(tree.GetRoot())
fmt.Println("Merkle Root: ", root)
proof, err := tree.GetProof(leaf1)
strProof := make([]string, len(proof))
if err != nil {
fmt.Println("GetProof ERR", err)
}
for _, v := range proof {
strProof = append(strProof, hexutil.Encode(v))
}
fmt.Println("02 proof: ", strProof)
}
多类型叶子节点
叶子节点拼接数据类型,可以将各种类型拼接(各种类型、类型数组等),匹配的验证合约能够获取足额数据,进行额外数据的处理
示例代码将地址和书来给你拼接,合约中通过额外的 mapping
记录,可以验证当前地址的剩余额度,
func MerkleWithMultiArgOZ() {
leaf1 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
smt.SolNumber("5000000000000000000"),
}
leaf2 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
smt.SolNumber("2500000000000000000"),
}
leaf3 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
smt.SolNumber("5000000000000000000"),
}
leaf4 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
smt.SolNumber("2500000000000000000"),
}
leaf5 := []interface{}{
smt.SolAddress("0x0000000000000000000000000000000000000000"),
smt.SolNumber("2500000000000000000"),
}
leaves := [][]interface{}{
leaf1,
leaf2,
leaf3,
leaf4,
leaf5,
}
tree, err := smt.Of(
leaves,
[]string{
smt.SOL_ADDRESS,
smt.SOL_UINT256,
})
if err != nil {
fmt.Println("Of ERR", err)
}
root := hexutil.Encode(tree.GetRoot())
fmt.Println("Merkle Root: ", root)
proof, err := tree.GetProof(leaf1)
strProof := make([]string, len(proof))
if err != nil {
fmt.Println("GetProof ERR", err)
}
for _, v := range proof {
strProof = append(strProof, hexutil.Encode(v))
}
fmt.Println("02 proof: ", strProof)
}