github.com/amazechain/amc@v0.1.3/common/hash/hash.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package hash 18 19 import ( 20 "bytes" 21 "github.com/amazechain/amc/common/crypto" 22 "github.com/amazechain/amc/common/types" 23 "github.com/amazechain/amc/internal/avm/rlp" 24 "sync" 25 26 "golang.org/x/crypto/sha3" 27 ) 28 29 // hasherPool holds LegacyKeccak256 hashers for rlpHash. 30 var HasherPool = sync.Pool{ 31 New: func() interface{} { return sha3.NewLegacyKeccak256() }, 32 } 33 34 // encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding. 35 var encodeBufferPool = sync.Pool{ 36 New: func() interface{} { return new(bytes.Buffer) }, 37 } 38 39 // DerivableList is the input to DeriveSha. 40 // It is implemented by the 'Transactions' and 'Receipts' types. 41 // This is internal, do not use these methods. 42 type DerivableList interface { 43 Len() int 44 EncodeIndex(int, *bytes.Buffer) 45 } 46 47 func encodeForDerive(list DerivableList, i int, buf *bytes.Buffer) []byte { 48 buf.Reset() 49 list.EncodeIndex(i, buf) 50 // It's really unfortunate that we need to do perform this copy. 51 // StackTrie holds onto the values until Hash is called, so the values 52 // written to it must not alias. 53 return types.CopyBytes(buf.Bytes()) 54 } 55 56 // DeriveSha creates the tree hashes of transactions and receipts in a block header. 57 func DeriveSha(list DerivableList) (h types.Hash) { 58 59 sha := HasherPool.Get().(crypto.KeccakState) 60 defer HasherPool.Put(sha) 61 sha.Reset() 62 63 valueBuf := encodeBufferPool.Get().(*bytes.Buffer) 64 defer encodeBufferPool.Put(valueBuf) 65 66 for i := 0; i < list.Len(); i++ { 67 value := encodeForDerive(list, i, valueBuf) 68 sha.Write(value) 69 } 70 sha.Read(h[:]) 71 return h 72 } 73 74 var ( 75 // NilHash sum(nil) 76 NilHash = types.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") 77 // EmptyUncleHash rlpHash([]*Header(nil)) 78 EmptyUncleHash = types.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") 79 ) 80 81 func RlpHash(x interface{}) (h types.Hash) { 82 sha := HasherPool.Get().(crypto.KeccakState) 83 defer HasherPool.Put(sha) 84 sha.Reset() 85 rlp.Encode(sha, x) 86 sha.Read(h[:]) 87 return h 88 } 89 90 // PrefixedRlpHash writes the prefix into the hasher before rlp-encoding x. 91 // It's used for typed transactions. 92 func PrefixedRlpHash(prefix byte, x interface{}) (h types.Hash) { 93 sha := HasherPool.Get().(crypto.KeccakState) 94 defer HasherPool.Put(sha) 95 sha.Reset() 96 sha.Write([]byte{prefix}) 97 rlp.Encode(sha, x) 98 sha.Read(h[:]) 99 return h 100 } 101 102 // Hash defines a function that returns the sha256 checksum of the data passed in. 103 // https://github.com/ethereum/consensus-specs/blob/v0.9.3/specs/core/0_beacon-chain.md#hash 104 func Hash(data []byte) [32]byte { 105 h, _ := HasherPool.Get().(crypto.KeccakState) 106 defer HasherPool.Put(h) 107 h.Reset() 108 109 var b [32]byte 110 111 // The hash interface never returns an error, for that reason 112 // we are not handling the error below. For reference, it is 113 // stated here https://golang.org/pkg/hash/#Hash 114 115 // #nosec G104 116 h.Write(data) 117 h.Read(b[:]) 118 119 return b 120 }