contracts, swarm: implement EIP-1577 (#19285)
* contracts/ens: update public resolver solidity code
* contracts/ens: update public resolver, update go bindings
* update build
* fix ens.sol
* contracts/ens: change contract interface
* contracts/ens: implement public resolver changes
* contracts/ens: added ENSRegistry contract
* contracts/ens: reinstate old contract code
* contracts/ens: update README.md
* contracts/ens: added test coverage for fallback contract
* contracts/ens: added support for fallback contract
* contracts/ens: removed unused contract code
* contracts/ens: add todo and decode multicodec stub
* add encode
* vendor: add ipfs cid libraries
* contracts/ens: cid sanity tests
* contracts/ens: more cid sanity checks
* contracts/ens: wip integration
* wip
* Revert "vendor: add ipfs cid libraries"
This reverts commit 29d9b6b294
.
* contracts/ens: removed multiformats dependencies
* contracts/ens: added decode tests
* contracts/ens: added eip spec test, minor changes to exiting tests
* contracts/ens: moved cid decoding to own file
* contracts/ens: added unit test to encode hash to content hash
* contracts/ens: removed unused code
* contracts/ens: fix ens tests to use cid decode and encode
* contracts/ens: adjust swarm multicodecs after pr merge
* contracts/ens: fix linter error
* constracts/ens: address PR comments
* cmd, contracts: make peoples lives easier
* contracts/ens: fix linter error
* contracts/ens: address PR comments
This commit is contained in:
121
contracts/ens/cid.go
Normal file
121
contracts/ens/cid.go
Normal file
@ -0,0 +1,121 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package ens
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const (
|
||||
cidv1 = 0x1
|
||||
|
||||
nsIpfs = 0xe3
|
||||
nsSwarm = 0xe4
|
||||
|
||||
swarmTypecode = 0xfa //swarm manifest, see https://github.com/multiformats/multicodec/blob/master/table.csv
|
||||
swarmHashtype = 0xd6 // BMT, see https://github.com/multiformats/multicodec/blob/master/table.csv
|
||||
|
||||
hashLength = 32
|
||||
)
|
||||
|
||||
// deocodeEIP1577ContentHash decodes a chain-stored content hash from an ENS record according to EIP-1577
|
||||
// a successful decode will result the different parts of the content hash in accordance to the CID spec
|
||||
// Note: only CIDv1 is supported
|
||||
func decodeEIP1577ContentHash(buf []byte) (storageNs, contentType, hashType, hashLength uint64, hash []byte, err error) {
|
||||
if len(buf) < 10 {
|
||||
return 0, 0, 0, 0, nil, errors.New("buffer too short")
|
||||
}
|
||||
|
||||
storageNs, n := binary.Uvarint(buf)
|
||||
|
||||
buf = buf[n:]
|
||||
vers, n := binary.Uvarint(buf)
|
||||
|
||||
if vers != 1 {
|
||||
return 0, 0, 0, 0, nil, fmt.Errorf("expected cid v1, got: %d", vers)
|
||||
}
|
||||
buf = buf[n:]
|
||||
contentType, n = binary.Uvarint(buf)
|
||||
|
||||
buf = buf[n:]
|
||||
hashType, n = binary.Uvarint(buf)
|
||||
|
||||
buf = buf[n:]
|
||||
hashLength, n = binary.Uvarint(buf)
|
||||
|
||||
hash = buf[n:]
|
||||
|
||||
if len(hash) != int(hashLength) {
|
||||
return 0, 0, 0, 0, nil, errors.New("hash length mismatch")
|
||||
}
|
||||
return storageNs, contentType, hashType, hashLength, hash, nil
|
||||
}
|
||||
|
||||
func extractContentHash(buf []byte) (common.Hash, error) {
|
||||
storageNs, _ /*contentType*/, _ /* hashType*/, decodedHashLength, hashBytes, err := decodeEIP1577ContentHash(buf)
|
||||
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
if storageNs != nsSwarm {
|
||||
return common.Hash{}, errors.New("unknown storage system")
|
||||
}
|
||||
|
||||
//todo: for the time being we implement loose enforcement for the EIP rules until ENS manager is updated
|
||||
/*if contentType != swarmTypecode {
|
||||
return common.Hash{}, errors.New("unknown content type")
|
||||
}
|
||||
|
||||
if hashType != swarmHashtype {
|
||||
return common.Hash{}, errors.New("unknown multihash type")
|
||||
}*/
|
||||
|
||||
if decodedHashLength != hashLength {
|
||||
return common.Hash{}, errors.New("odd hash length, swarm expects 32 bytes")
|
||||
}
|
||||
|
||||
if len(hashBytes) != int(hashLength) {
|
||||
return common.Hash{}, errors.New("hash length mismatch")
|
||||
}
|
||||
|
||||
return common.BytesToHash(buf), nil
|
||||
}
|
||||
|
||||
func EncodeSwarmHash(hash common.Hash) ([]byte, error) {
|
||||
var cidBytes []byte
|
||||
var headerBytes = []byte{
|
||||
nsSwarm, //swarm namespace
|
||||
cidv1, // CIDv1
|
||||
swarmTypecode, // swarm hash
|
||||
swarmHashtype, // swarm bmt hash
|
||||
hashLength, //hash length. 32 bytes
|
||||
}
|
||||
|
||||
varintbuf := make([]byte, binary.MaxVarintLen64)
|
||||
for _, v := range headerBytes {
|
||||
n := binary.PutUvarint(varintbuf, uint64(v))
|
||||
cidBytes = append(cidBytes, varintbuf[:n]...)
|
||||
}
|
||||
|
||||
cidBytes = append(cidBytes, hash[:]...)
|
||||
return cidBytes, nil
|
||||
}
|
Reference in New Issue
Block a user