github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/contracts/ens/cid.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package ens 18 19 import ( 20 "encoding/binary" 21 "errors" 22 "fmt" 23 24 "github.com/ethereum/go-ethereum/common" 25 ) 26 27 const ( 28 cidv1 = 0x1 29 30 nsIpfs = 0xe3 31 nsSwarm = 0xe4 32 33 swarmTypecode = 0xfa // swarm manifest, see https://github.com/multiformats/multicodec/blob/master/table.csv 34 swarmHashtype = 0x1b // keccak256, see https://github.com/multiformats/multicodec/blob/master/table.csv 35 36 hashLength = 32 37 ) 38 39 // deocodeEIP1577ContentHash decodes a chain-stored content hash from an ENS record according to EIP-1577 40 // a successful decode will result the different parts of the content hash in accordance to the CID spec 41 // Note: only CIDv1 is supported 42 func decodeEIP1577ContentHash(buf []byte) (storageNs, contentType, hashType, hashLength uint64, hash []byte, err error) { 43 if len(buf) < 10 { 44 return 0, 0, 0, 0, nil, errors.New("buffer too short") 45 } 46 47 storageNs, n := binary.Uvarint(buf) 48 49 buf = buf[n:] 50 vers, n := binary.Uvarint(buf) 51 52 if vers != 1 { 53 return 0, 0, 0, 0, nil, fmt.Errorf("expected cid v1, got: %d", vers) 54 } 55 buf = buf[n:] 56 contentType, n = binary.Uvarint(buf) 57 58 buf = buf[n:] 59 hashType, n = binary.Uvarint(buf) 60 61 buf = buf[n:] 62 hashLength, n = binary.Uvarint(buf) 63 64 hash = buf[n:] 65 66 if len(hash) != int(hashLength) { 67 return 0, 0, 0, 0, nil, errors.New("hash length mismatch") 68 } 69 return storageNs, contentType, hashType, hashLength, hash, nil 70 } 71 72 func extractContentHash(buf []byte) (common.Hash, error) { 73 storageNs, _ /*contentType*/, _ /* hashType*/, decodedHashLength, hashBytes, err := decodeEIP1577ContentHash(buf) 74 75 if err != nil { 76 return common.Hash{}, err 77 } 78 79 if storageNs != nsSwarm { 80 return common.Hash{}, errors.New("unknown storage system") 81 } 82 83 //todo: for the time being we implement loose enforcement for the EIP rules until ENS manager is updated 84 /*if contentType != swarmTypecode { 85 return common.Hash{}, errors.New("unknown content type") 86 } 87 88 if hashType != swarmHashtype { 89 return common.Hash{}, errors.New("unknown multihash type") 90 }*/ 91 92 if decodedHashLength != hashLength { 93 return common.Hash{}, errors.New("odd hash length, swarm expects 32 bytes") 94 } 95 96 if len(hashBytes) != int(hashLength) { 97 return common.Hash{}, errors.New("hash length mismatch") 98 } 99 100 return common.BytesToHash(buf), nil 101 } 102 103 func EncodeSwarmHash(hash common.Hash) ([]byte, error) { 104 var cidBytes []byte 105 var headerBytes = []byte{ 106 nsSwarm, //swarm namespace 107 cidv1, // CIDv1 108 swarmTypecode, // swarm hash 109 swarmHashtype, // keccak256 hash 110 hashLength, //hash length. 32 bytes 111 } 112 113 varintbuf := make([]byte, binary.MaxVarintLen64) 114 for _, v := range headerBytes { 115 n := binary.PutUvarint(varintbuf, uint64(v)) 116 cidBytes = append(cidBytes, varintbuf[:n]...) 117 } 118 119 cidBytes = append(cidBytes, hash[:]...) 120 return cidBytes, nil 121 }