From 8b1edde801db40053c10b7659f31f4b4b94c9da1 Mon Sep 17 00:00:00 2001 From: apratt3377 Date: Mon, 10 Sep 2018 15:44:07 -0400 Subject: [PATCH 1/6] allow private transactions with abigen --- accounts/abi/bind/base.go | 65 ++++++++++++++++++++++++++++++++++++++- core/types/transaction.go | 6 +++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index b40bd65e8..4242c8371 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -25,8 +25,11 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/rlp" ) // SignerFn is a signer function callback when a contract requires a method to @@ -48,6 +51,9 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) + PrivateFrom string // The public key of the Constellation identity to send this tx from. + PrivateFor []string // The public keys of the Constellation identities this tx is intended for. + Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) GasLimit *big.Int // Gas limit to set for the transaction execution (nil = estimate + 10%) @@ -205,13 +211,27 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i return nil, fmt.Errorf("failed to estimate gas needed: %v", err) } } - // Create the transaction, sign it and schedule it for execution + + // Create the raw transaction. var rawTx *types.Transaction if contract == nil { rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input) } else { rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input) } + + // If this transaction is private, we need to substitute the data payload + // with one from constelation. + if len(opts.PrivateFor) > 0 { + fmt.Printf("prepareing: for %v from %v", opts.PrivateFor, opts.PrivateFrom) + rawTx, err = preparePrivateTransaction( + ensureContext(opts.Context), rawTx, opts.PrivateFrom, opts.PrivateFor) + if err != nil { + return nil, err + } + } + + // Sign the transaction and submit it to the mempool. if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") } @@ -225,6 +245,49 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i return signedTx, nil } +func preparePrivateTransaction(ctx context.Context, tx *types.Transaction, privateFrom string, privateFor []string) (*types.Transaction, error) { + raw, _ := rlp.EncodeToBytes(tx) + + privTxBytes, err := sendToPrivateTransactionManager(ctx, raw, privateFrom, privateFor) + if err != nil { + return nil, err + } + + tx = new(types.Transaction) + if err := rlp.DecodeBytes(privTxBytes, tx); err != nil { + return nil, err + } + + return tx, nil +} + +func sendToPrivateTransactionManager(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { + if len(privateFor) == 0 { + return nil, errors.New("need at least one private for") + } + tx := new(types.Transaction) + if err := rlp.DecodeBytes(encodedTx, tx); err != nil { + return nil, err + } + + if private.P == nil { + return nil, errors.New("constellation not set up") + } + data, err := private.P.Send(tx.Data(), privateFrom, privateFor) + if err != nil { + return nil, err + } + + tx.SetPrivate() + tx.SetData(data) + newEncoded, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + + return hexutil.Bytes(newEncoded), nil +} + func ensureContext(ctx context.Context) context.Context { if ctx == nil { return context.TODO() diff --git a/core/types/transaction.go b/core/types/transaction.go index 31f88ff14..9d2078ca4 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -182,7 +182,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { return nil } -func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } +func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } +func (tx *Transaction) SetData(data []byte) { + tx.data.Payload = common.CopyBytes(data) +} + func (tx *Transaction) Gas() *big.Int { return new(big.Int).Set(tx.data.GasLimit) } func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } From 3312757c211e88c48aca316e8ae83eb0bc441a70 Mon Sep 17 00:00:00 2001 From: apratt3377 Date: Wed, 12 Sep 2018 10:35:29 -0400 Subject: [PATCH 2/6] add simulated abigen example --- accounts/abi/bind/backend.go | 3 + accounts/abi/bind/backends/simulated.go | 21 + accounts/abi/bind/base.go | 37 +- contracts/ens_private/README.md | 20 + contracts/ens_private/contract/ens.go | 921 ++++++++++++++++++++++++ contracts/ens_private/contract/ens.sol | 226 ++++++ contracts/ens_private/ens.go | 183 +++++ contracts/ens_private/ens_test.go | 72 ++ eth/bind.go | 29 + ethclient/ethclient.go | 28 + 10 files changed, 1506 insertions(+), 34 deletions(-) create mode 100644 contracts/ens_private/README.md create mode 100644 contracts/ens_private/contract/ens.go create mode 100644 contracts/ens_private/contract/ens.sol create mode 100644 contracts/ens_private/ens.go create mode 100644 contracts/ens_private/ens_test.go diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 25b61928e..cac3cefb1 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" ) @@ -88,6 +89,8 @@ type ContractTransactor interface { EstimateGas(ctx context.Context, call ethereum.CallMsg) (usedGas *big.Int, err error) // SendTransaction injects the transaction into the pending pool for execution. SendTransaction(ctx context.Context, tx *types.Transaction) error + + PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) } // ContractBackend defines the methods needed to work with contracts on a read-write basis. diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 790d84a48..b761a0304 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -35,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" ) // This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend. @@ -287,6 +289,25 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa return nil } +func (b *SimulatedBackend) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { + if len(privateFor) == 0 { + return nil, errors.New("need at least one private for") + } + tx := new(types.Transaction) + if err := rlp.DecodeBytes(encodedTx, tx); err != nil { + return nil, err + } + data := tx.Data() + tx.SetPrivate() + tx.SetData(data) + newEncoded, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + + return hexutil.Bytes(newEncoded), nil +} + // JumpTimeInSeconds adds skip seconds to the clock func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { b.mu.Lock() diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 4242c8371..879f963b4 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -25,10 +25,8 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/rlp" ) @@ -223,8 +221,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i // If this transaction is private, we need to substitute the data payload // with one from constelation. if len(opts.PrivateFor) > 0 { - fmt.Printf("prepareing: for %v from %v", opts.PrivateFor, opts.PrivateFrom) - rawTx, err = preparePrivateTransaction( + rawTx, err = c.preparePrivateTransaction( ensureContext(opts.Context), rawTx, opts.PrivateFrom, opts.PrivateFor) if err != nil { return nil, err @@ -245,10 +242,10 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i return signedTx, nil } -func preparePrivateTransaction(ctx context.Context, tx *types.Transaction, privateFrom string, privateFor []string) (*types.Transaction, error) { +func (c *BoundContract) preparePrivateTransaction(ctx context.Context, tx *types.Transaction, privateFrom string, privateFor []string) (*types.Transaction, error) { raw, _ := rlp.EncodeToBytes(tx) - privTxBytes, err := sendToPrivateTransactionManager(ctx, raw, privateFrom, privateFor) + privTxBytes, err := c.transactor.PreparePrivateTransaction(ctx, raw, privateFrom, privateFor) if err != nil { return nil, err } @@ -257,37 +254,9 @@ func preparePrivateTransaction(ctx context.Context, tx *types.Transaction, priva if err := rlp.DecodeBytes(privTxBytes, tx); err != nil { return nil, err } - return tx, nil } -func sendToPrivateTransactionManager(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { - if len(privateFor) == 0 { - return nil, errors.New("need at least one private for") - } - tx := new(types.Transaction) - if err := rlp.DecodeBytes(encodedTx, tx); err != nil { - return nil, err - } - - if private.P == nil { - return nil, errors.New("constellation not set up") - } - data, err := private.P.Send(tx.Data(), privateFrom, privateFor) - if err != nil { - return nil, err - } - - tx.SetPrivate() - tx.SetData(data) - newEncoded, err := rlp.EncodeToBytes(tx) - if err != nil { - return nil, err - } - - return hexutil.Bytes(newEncoded), nil -} - func ensureContext(ctx context.Context) context.Context { if ctx == nil { return context.TODO() diff --git a/contracts/ens_private/README.md b/contracts/ens_private/README.md new file mode 100644 index 000000000..c09b47e39 --- /dev/null +++ b/contracts/ens_private/README.md @@ -0,0 +1,20 @@ +# Swarm ENS interface + +## Usage + +Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/ethereum/EIPs/issues/137). +This package offers a simple binding that streamlines the registration of arbitrary UTF8 domain names to swarm content hashes. + +## Development + +The SOL file in contract subdirectory implements the ENS root registry, a simple +first-in, first-served registrar for the root namespace, and a simple resolver contract; +they're used in tests, and can be used to deploy these contracts for your own purposes. + +The solidity source code can be found at [github.com/arachnid/ens/](https://github.com/arachnid/ens/). + +The go bindings for ENS contracts are generated using `abigen` via the go generator: + +```shell +go generate ./contracts/ens +``` diff --git a/contracts/ens_private/contract/ens.go b/contracts/ens_private/contract/ens.go new file mode 100644 index 000000000..aca16de50 --- /dev/null +++ b/contracts/ens_private/contract/ens.go @@ -0,0 +1,921 @@ +// This file is an automatically generated Go binding. Do not modify as any +// change will likely be lost upon the next re-generation! + +package contract + +import ( + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// ENSABI is the input ABI used to generate the binding from. +const ENSABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"label","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"inputs":[{"name":"owner","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"resolver","type":"address"}],"name":"NewResolver","type":"event"}]` + +// ENSBin is the compiled bytecode used for deploying new contracts. +const ENSBin = `0x606060405260405160208061032683395060806040525160008080526020527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58054600160a060020a03191682179055506102c88061005e6000396000f3606060405260e060020a60003504630178b8bf811461004757806302571be31461006e57806306ab5923146100915780631896f70a146100c85780635b0fc9c3146100fc575b005b610130600435600081815260208190526040902060010154600160a060020a03165b919050565b610130600435600081815260208190526040902054600160a060020a0316610069565b6100456004356024356044356000838152602081905260408120548490600160a060020a0390811633919091161461014d57610002565b6100456004356024356000828152602081905260409020548290600160a060020a039081163391909116146101e757610002565b6100456004356024356000828152602081905260409020548290600160a060020a0390811633919091161461025957610002565b60408051600160a060020a03929092168252519081900360200190f35b60408051868152602081810187905282519182900383018220600160a060020a03871683529251929450869288927fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8292908290030190a382600060005060008460001916815260200190815260200160002060005060000160006101000a815481600160a060020a03021916908302179055505050505050565b60408051600160a060020a0384168152905184917f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0919081900360200190a2506000828152602081905260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916821790555050565b60408051600160a060020a0384168152905184917fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266919081900360200190a2506000828152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff191682179055505056` + +// DeployENS deploys a new Ethereum contract, binding an instance of ENS to it. +func DeployENS(auth *bind.TransactOpts, backend bind.ContractBackend, owner common.Address) (common.Address, *types.Transaction, *ENS, error) { + parsed, err := abi.JSON(strings.NewReader(ENSABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ENSBin), backend, owner) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}}, nil +} + +// ENS is an auto generated Go binding around an Ethereum contract. +type ENS struct { + ENSCaller // Read-only binding to the contract + ENSTransactor // Write-only binding to the contract +} + +// ENSCaller is an auto generated read-only Go binding around an Ethereum contract. +type ENSCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ENSTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ENSTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ENSSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ENSSession struct { + Contract *ENS // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ENSCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ENSCallerSession struct { + Contract *ENSCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ENSTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ENSTransactorSession struct { + Contract *ENSTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ENSRaw is an auto generated low-level Go binding around an Ethereum contract. +type ENSRaw struct { + Contract *ENS // Generic contract binding to access the raw methods on +} + +// ENSCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ENSCallerRaw struct { + Contract *ENSCaller // Generic read-only contract binding to access the raw methods on +} + +// ENSTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ENSTransactorRaw struct { + Contract *ENSTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewENS creates a new instance of ENS, bound to a specific deployed contract. +func NewENS(address common.Address, backend bind.ContractBackend) (*ENS, error) { + contract, err := bindENS(address, backend, backend) + if err != nil { + return nil, err + } + return &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}}, nil +} + +// NewENSCaller creates a new read-only instance of ENS, bound to a specific deployed contract. +func NewENSCaller(address common.Address, caller bind.ContractCaller) (*ENSCaller, error) { + contract, err := bindENS(address, caller, nil) + if err != nil { + return nil, err + } + return &ENSCaller{contract: contract}, nil +} + +// NewENSTransactor creates a new write-only instance of ENS, bound to a specific deployed contract. +func NewENSTransactor(address common.Address, transactor bind.ContractTransactor) (*ENSTransactor, error) { + contract, err := bindENS(address, nil, transactor) + if err != nil { + return nil, err + } + return &ENSTransactor{contract: contract}, nil +} + +// bindENS binds a generic wrapper to an already deployed contract. +func bindENS(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ENSABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ENS *ENSRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _ENS.Contract.ENSCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ENS *ENSRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ENS.Contract.ENSTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ENS *ENSRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ENS.Contract.ENSTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ENS *ENSCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _ENS.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ENS *ENSTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ENS.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ENS *ENSTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ENS.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x02571be3. +// +// Solidity: function owner(node bytes32) constant returns(address) +func (_ENS *ENSCaller) Owner(opts *bind.CallOpts, node [32]byte) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _ENS.contract.Call(opts, out, "owner", node) + return *ret0, err +} + +// Owner is a free data retrieval call binding the contract method 0x02571be3. +// +// Solidity: function owner(node bytes32) constant returns(address) +func (_ENS *ENSSession) Owner(node [32]byte) (common.Address, error) { + return _ENS.Contract.Owner(&_ENS.CallOpts, node) +} + +// Owner is a free data retrieval call binding the contract method 0x02571be3. +// +// Solidity: function owner(node bytes32) constant returns(address) +func (_ENS *ENSCallerSession) Owner(node [32]byte) (common.Address, error) { + return _ENS.Contract.Owner(&_ENS.CallOpts, node) +} + +// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. +// +// Solidity: function resolver(node bytes32) constant returns(address) +func (_ENS *ENSCaller) Resolver(opts *bind.CallOpts, node [32]byte) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _ENS.contract.Call(opts, out, "resolver", node) + return *ret0, err +} + +// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. +// +// Solidity: function resolver(node bytes32) constant returns(address) +func (_ENS *ENSSession) Resolver(node [32]byte) (common.Address, error) { + return _ENS.Contract.Resolver(&_ENS.CallOpts, node) +} + +// Resolver is a free data retrieval call binding the contract method 0x0178b8bf. +// +// Solidity: function resolver(node bytes32) constant returns(address) +func (_ENS *ENSCallerSession) Resolver(node [32]byte) (common.Address, error) { + return _ENS.Contract.Resolver(&_ENS.CallOpts, node) +} + +// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. +// +// Solidity: function setOwner(node bytes32, owner address) returns() +func (_ENS *ENSTransactor) SetOwner(opts *bind.TransactOpts, node [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.contract.Transact(opts, "setOwner", node, owner) +} + +// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. +// +// Solidity: function setOwner(node bytes32, owner address) returns() +func (_ENS *ENSSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner) +} + +// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3. +// +// Solidity: function setOwner(node bytes32, owner address) returns() +func (_ENS *ENSTransactorSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner) +} + +// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. +// +// Solidity: function setResolver(node bytes32, resolver address) returns() +func (_ENS *ENSTransactor) SetResolver(opts *bind.TransactOpts, node [32]byte, resolver common.Address) (*types.Transaction, error) { + return _ENS.contract.Transact(opts, "setResolver", node, resolver) +} + +// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. +// +// Solidity: function setResolver(node bytes32, resolver address) returns() +func (_ENS *ENSSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver) +} + +// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a. +// +// Solidity: function setResolver(node bytes32, resolver address) returns() +func (_ENS *ENSTransactorSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver) +} + +// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. +// +// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() +func (_ENS *ENSTransactor) SetSubnodeOwner(opts *bind.TransactOpts, node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.contract.Transact(opts, "setSubnodeOwner", node, label, owner) +} + +// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. +// +// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() +func (_ENS *ENSSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner) +} + +// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923. +// +// Solidity: function setSubnodeOwner(node bytes32, label bytes32, owner address) returns() +func (_ENS *ENSTransactorSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) { + return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner) +} + +// FIFSRegistrarABI is the input ABI used to generate the binding from. +const FIFSRegistrarABI = `[{"constant":false,"inputs":[{"name":"subnode","type":"bytes32"},{"name":"owner","type":"address"}],"name":"register","outputs":[],"type":"function"},{"inputs":[{"name":"ensAddr","type":"address"},{"name":"node","type":"bytes32"}],"type":"constructor"}]` + +// FIFSRegistrarBin is the compiled bytecode used for deploying new contracts. +const FIFSRegistrarBin = `0x6060604081815280610620833960a090525160805160008054600160a060020a031916831790558160a0610367806100878339018082600160a060020a03168152602001915050604051809103906000f0600160006101000a815481600160a060020a0302191690830217905550806002600050819055505050610232806103ee6000396000f3606060405260405160208061036783395060806040525160008054600160a060020a0319168217905550610330806100376000396000f36060604052361561004b5760e060020a60003504632dff694181146100535780633b3b57de1461007557806341b9dc2b146100a0578063c3d014d614610139578063d5fa2b00146101b2575b61022b610002565b61022d6004356000818152600260205260408120549081141561027057610002565b61023f600435600081815260016020526040812054600160a060020a03169081141561027057610002565b61025c60043560243560007f6164647200000000000000000000000000000000000000000000000000000000821480156100f05750600083815260016020526040812054600160a060020a031614155b8061013257507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610132575060008381526002602052604081205414155b9392505050565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a031691909114905061027557610002565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a03169190911490506102c157610002565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b919050565b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916851790558151600160a060020a0385168152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a250505056606060405260e060020a6000350463d22057a9811461001b575b005b61001960043560243560025460408051918252602082810185905260008054835194859003840185207f02571be300000000000000000000000000000000000000000000000000000000865260048601819052935193949193600160a060020a03909116926302571be39260248181019391829003018187876161da5a03f11561000257505060405151915050600160a060020a0381166000148015906100d4575033600160a060020a031681600160a060020a031614155b156100de57610002565b60408051600080546002547f06ab592300000000000000000000000000000000000000000000000000000000845260048401526024830188905230600160a060020a03908116604485015293519316926306ab5923926064818101939291829003018183876161da5a03f11561000257505060008054600154604080517f1896f70a00000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a0392831660248201529051929091169350631896f70a926044828101939192829003018183876161da5a03f11561000257505060008054604080517f5b0fc9c300000000000000000000000000000000000000000000000000000000815260048101879052600160a060020a0388811660248301529151929091169350635b0fc9c3926044828101939192829003018183876161da5a03f115610002575050505050505056` + +// DeployFIFSRegistrar deploys a new Ethereum contract, binding an instance of FIFSRegistrar to it. +func DeployFIFSRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address, node [32]byte) (common.Address, *types.Transaction, *FIFSRegistrar, error) { + parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(FIFSRegistrarBin), backend, ensAddr, node) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}}, nil +} + +// FIFSRegistrar is an auto generated Go binding around an Ethereum contract. +type FIFSRegistrar struct { + FIFSRegistrarCaller // Read-only binding to the contract + FIFSRegistrarTransactor // Write-only binding to the contract +} + +// FIFSRegistrarCaller is an auto generated read-only Go binding around an Ethereum contract. +type FIFSRegistrarCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// FIFSRegistrarTransactor is an auto generated write-only Go binding around an Ethereum contract. +type FIFSRegistrarTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// FIFSRegistrarSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type FIFSRegistrarSession struct { + Contract *FIFSRegistrar // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// FIFSRegistrarCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type FIFSRegistrarCallerSession struct { + Contract *FIFSRegistrarCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// FIFSRegistrarTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type FIFSRegistrarTransactorSession struct { + Contract *FIFSRegistrarTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// FIFSRegistrarRaw is an auto generated low-level Go binding around an Ethereum contract. +type FIFSRegistrarRaw struct { + Contract *FIFSRegistrar // Generic contract binding to access the raw methods on +} + +// FIFSRegistrarCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type FIFSRegistrarCallerRaw struct { + Contract *FIFSRegistrarCaller // Generic read-only contract binding to access the raw methods on +} + +// FIFSRegistrarTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type FIFSRegistrarTransactorRaw struct { + Contract *FIFSRegistrarTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewFIFSRegistrar creates a new instance of FIFSRegistrar, bound to a specific deployed contract. +func NewFIFSRegistrar(address common.Address, backend bind.ContractBackend) (*FIFSRegistrar, error) { + contract, err := bindFIFSRegistrar(address, backend, backend) + if err != nil { + return nil, err + } + return &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}}, nil +} + +// NewFIFSRegistrarCaller creates a new read-only instance of FIFSRegistrar, bound to a specific deployed contract. +func NewFIFSRegistrarCaller(address common.Address, caller bind.ContractCaller) (*FIFSRegistrarCaller, error) { + contract, err := bindFIFSRegistrar(address, caller, nil) + if err != nil { + return nil, err + } + return &FIFSRegistrarCaller{contract: contract}, nil +} + +// NewFIFSRegistrarTransactor creates a new write-only instance of FIFSRegistrar, bound to a specific deployed contract. +func NewFIFSRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*FIFSRegistrarTransactor, error) { + contract, err := bindFIFSRegistrar(address, nil, transactor) + if err != nil { + return nil, err + } + return &FIFSRegistrarTransactor{contract: contract}, nil +} + +// bindFIFSRegistrar binds a generic wrapper to an already deployed contract. +func bindFIFSRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_FIFSRegistrar *FIFSRegistrarRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _FIFSRegistrar.Contract.FIFSRegistrarCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_FIFSRegistrar *FIFSRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_FIFSRegistrar *FIFSRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_FIFSRegistrar *FIFSRegistrarCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _FIFSRegistrar.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.contract.Transact(opts, method, params...) +} + +// Register is a paid mutator transaction binding the contract method 0xd22057a9. +// +// Solidity: function register(subnode bytes32, owner address) returns() +func (_FIFSRegistrar *FIFSRegistrarTransactor) Register(opts *bind.TransactOpts, subnode [32]byte, owner common.Address) (*types.Transaction, error) { + return _FIFSRegistrar.contract.Transact(opts, "register", subnode, owner) +} + +// Register is a paid mutator transaction binding the contract method 0xd22057a9. +// +// Solidity: function register(subnode bytes32, owner address) returns() +func (_FIFSRegistrar *FIFSRegistrarSession) Register(subnode [32]byte, owner common.Address) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, subnode, owner) +} + +// Register is a paid mutator transaction binding the contract method 0xd22057a9. +// +// Solidity: function register(subnode bytes32, owner address) returns() +func (_FIFSRegistrar *FIFSRegistrarTransactorSession) Register(subnode [32]byte, owner common.Address) (*types.Transaction, error) { + return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, subnode, owner) +} + +// PublicResolverABI is the input ABI used to generate the binding from. +const PublicResolverABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"content","outputs":[{"name":"ret","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"addr","outputs":[{"name":"ret","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"kind","type":"bytes32"}],"name":"has","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"hash","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"addr","type":"address"}],"name":"setAddr","outputs":[],"type":"function"},{"inputs":[{"name":"ensAddr","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes32"}],"name":"ContentChanged","type":"event"}]` + +// PublicResolverBin is the compiled bytecode used for deploying new contracts. +const PublicResolverBin = `0x606060405260405160208061036783395060806040525160008054600160a060020a0319168217905550610330806100376000396000f36060604052361561004b5760e060020a60003504632dff694181146100535780633b3b57de1461007557806341b9dc2b146100a0578063c3d014d614610139578063d5fa2b00146101b2575b61022b610002565b61022d6004356000818152600260205260408120549081141561027057610002565b61023f600435600081815260016020526040812054600160a060020a03169081141561027057610002565b61025c60043560243560007f6164647200000000000000000000000000000000000000000000000000000000821480156100f05750600083815260016020526040812054600160a060020a031614155b8061013257507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610132575060008381526002602052604081205414155b9392505050565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a031691909114905061027557610002565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a03169190911490506102c157610002565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b919050565b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916851790558151600160a060020a0385168152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a250505056` + +// DeployPublicResolver deploys a new Ethereum contract, binding an instance of PublicResolver to it. +func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address) (common.Address, *types.Transaction, *PublicResolver, error) { + parsed, err := abi.JSON(strings.NewReader(PublicResolverABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PublicResolverBin), backend, ensAddr) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}}, nil +} + +// PublicResolver is an auto generated Go binding around an Ethereum contract. +type PublicResolver struct { + PublicResolverCaller // Read-only binding to the contract + PublicResolverTransactor // Write-only binding to the contract +} + +// PublicResolverCaller is an auto generated read-only Go binding around an Ethereum contract. +type PublicResolverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PublicResolverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PublicResolverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PublicResolverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PublicResolverSession struct { + Contract *PublicResolver // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PublicResolverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PublicResolverCallerSession struct { + Contract *PublicResolverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PublicResolverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PublicResolverTransactorSession struct { + Contract *PublicResolverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PublicResolverRaw is an auto generated low-level Go binding around an Ethereum contract. +type PublicResolverRaw struct { + Contract *PublicResolver // Generic contract binding to access the raw methods on +} + +// PublicResolverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PublicResolverCallerRaw struct { + Contract *PublicResolverCaller // Generic read-only contract binding to access the raw methods on +} + +// PublicResolverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PublicResolverTransactorRaw struct { + Contract *PublicResolverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPublicResolver creates a new instance of PublicResolver, bound to a specific deployed contract. +func NewPublicResolver(address common.Address, backend bind.ContractBackend) (*PublicResolver, error) { + contract, err := bindPublicResolver(address, backend, backend) + if err != nil { + return nil, err + } + return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}}, nil +} + +// NewPublicResolverCaller creates a new read-only instance of PublicResolver, bound to a specific deployed contract. +func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) (*PublicResolverCaller, error) { + contract, err := bindPublicResolver(address, caller, nil) + if err != nil { + return nil, err + } + return &PublicResolverCaller{contract: contract}, nil +} + +// NewPublicResolverTransactor creates a new write-only instance of PublicResolver, bound to a specific deployed contract. +func NewPublicResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*PublicResolverTransactor, error) { + contract, err := bindPublicResolver(address, nil, transactor) + if err != nil { + return nil, err + } + return &PublicResolverTransactor{contract: contract}, nil +} + +// bindPublicResolver binds a generic wrapper to an already deployed contract. +func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(PublicResolverABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PublicResolver *PublicResolverRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PublicResolver.Contract.PublicResolverCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PublicResolver *PublicResolverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PublicResolver.Contract.PublicResolverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PublicResolver *PublicResolverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PublicResolver.Contract.PublicResolverTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PublicResolver *PublicResolverCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _PublicResolver.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PublicResolver *PublicResolverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PublicResolver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PublicResolver *PublicResolverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PublicResolver.Contract.contract.Transact(opts, method, params...) +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_PublicResolver *PublicResolverCaller) Addr(opts *bind.CallOpts, node [32]byte) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _PublicResolver.contract.Call(opts, out, "addr", node) + return *ret0, err +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_PublicResolver *PublicResolverSession) Addr(node [32]byte) (common.Address, error) { + return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node) +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_PublicResolver *PublicResolverCallerSession) Addr(node [32]byte) (common.Address, error) { + return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node) +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_PublicResolver *PublicResolverCaller) Content(opts *bind.CallOpts, node [32]byte) ([32]byte, error) { + var ( + ret0 = new([32]byte) + ) + out := ret0 + err := _PublicResolver.contract.Call(opts, out, "content", node) + return *ret0, err +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_PublicResolver *PublicResolverSession) Content(node [32]byte) ([32]byte, error) { + return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node) +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_PublicResolver *PublicResolverCallerSession) Content(node [32]byte) ([32]byte, error) { + return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_PublicResolver *PublicResolverTransactor) Has(opts *bind.TransactOpts, node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _PublicResolver.contract.Transact(opts, "has", node, kind) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_PublicResolver *PublicResolverSession) Has(node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _PublicResolver.Contract.Has(&_PublicResolver.TransactOpts, node, kind) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_PublicResolver *PublicResolverTransactorSession) Has(node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _PublicResolver.Contract.Has(&_PublicResolver.TransactOpts, node, kind) +} + +// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. +// +// Solidity: function setAddr(node bytes32, addr address) returns() +func (_PublicResolver *PublicResolverTransactor) SetAddr(opts *bind.TransactOpts, node [32]byte, addr common.Address) (*types.Transaction, error) { + return _PublicResolver.contract.Transact(opts, "setAddr", node, addr) +} + +// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. +// +// Solidity: function setAddr(node bytes32, addr address) returns() +func (_PublicResolver *PublicResolverSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) { + return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr) +} + +// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00. +// +// Solidity: function setAddr(node bytes32, addr address) returns() +func (_PublicResolver *PublicResolverTransactorSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) { + return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr) +} + +// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. +// +// Solidity: function setContent(node bytes32, hash bytes32) returns() +func (_PublicResolver *PublicResolverTransactor) SetContent(opts *bind.TransactOpts, node [32]byte, hash [32]byte) (*types.Transaction, error) { + return _PublicResolver.contract.Transact(opts, "setContent", node, hash) +} + +// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. +// +// Solidity: function setContent(node bytes32, hash bytes32) returns() +func (_PublicResolver *PublicResolverSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) { + return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash) +} + +// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6. +// +// Solidity: function setContent(node bytes32, hash bytes32) returns() +func (_PublicResolver *PublicResolverTransactorSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) { + return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash) +} + +// ResolverABI is the input ABI used to generate the binding from. +const ResolverABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"content","outputs":[{"name":"ret","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"addr","outputs":[{"name":"ret","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"kind","type":"bytes32"}],"name":"has","outputs":[{"name":"","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes32"}],"name":"ContentChanged","type":"event"}]` + +// ResolverBin is the compiled bytecode used for deploying new contracts. +const ResolverBin = `0x` + +// DeployResolver deploys a new Ethereum contract, binding an instance of Resolver to it. +func DeployResolver(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Resolver, error) { + parsed, err := abi.JSON(strings.NewReader(ResolverABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ResolverBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}}, nil +} + +// Resolver is an auto generated Go binding around an Ethereum contract. +type Resolver struct { + ResolverCaller // Read-only binding to the contract + ResolverTransactor // Write-only binding to the contract +} + +// ResolverCaller is an auto generated read-only Go binding around an Ethereum contract. +type ResolverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ResolverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ResolverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ResolverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ResolverSession struct { + Contract *Resolver // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ResolverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ResolverCallerSession struct { + Contract *ResolverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ResolverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ResolverTransactorSession struct { + Contract *ResolverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ResolverRaw is an auto generated low-level Go binding around an Ethereum contract. +type ResolverRaw struct { + Contract *Resolver // Generic contract binding to access the raw methods on +} + +// ResolverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ResolverCallerRaw struct { + Contract *ResolverCaller // Generic read-only contract binding to access the raw methods on +} + +// ResolverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ResolverTransactorRaw struct { + Contract *ResolverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewResolver creates a new instance of Resolver, bound to a specific deployed contract. +func NewResolver(address common.Address, backend bind.ContractBackend) (*Resolver, error) { + contract, err := bindResolver(address, backend, backend) + if err != nil { + return nil, err + } + return &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}}, nil +} + +// NewResolverCaller creates a new read-only instance of Resolver, bound to a specific deployed contract. +func NewResolverCaller(address common.Address, caller bind.ContractCaller) (*ResolverCaller, error) { + contract, err := bindResolver(address, caller, nil) + if err != nil { + return nil, err + } + return &ResolverCaller{contract: contract}, nil +} + +// NewResolverTransactor creates a new write-only instance of Resolver, bound to a specific deployed contract. +func NewResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*ResolverTransactor, error) { + contract, err := bindResolver(address, nil, transactor) + if err != nil { + return nil, err + } + return &ResolverTransactor{contract: contract}, nil +} + +// bindResolver binds a generic wrapper to an already deployed contract. +func bindResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ResolverABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Resolver *ResolverRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _Resolver.Contract.ResolverCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Resolver *ResolverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Resolver.Contract.ResolverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Resolver *ResolverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Resolver.Contract.ResolverTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Resolver *ResolverCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _Resolver.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Resolver *ResolverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Resolver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Resolver *ResolverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Resolver.Contract.contract.Transact(opts, method, params...) +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_Resolver *ResolverCaller) Addr(opts *bind.CallOpts, node [32]byte) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _Resolver.contract.Call(opts, out, "addr", node) + return *ret0, err +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_Resolver *ResolverSession) Addr(node [32]byte) (common.Address, error) { + return _Resolver.Contract.Addr(&_Resolver.CallOpts, node) +} + +// Addr is a free data retrieval call binding the contract method 0x3b3b57de. +// +// Solidity: function addr(node bytes32) constant returns(ret address) +func (_Resolver *ResolverCallerSession) Addr(node [32]byte) (common.Address, error) { + return _Resolver.Contract.Addr(&_Resolver.CallOpts, node) +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_Resolver *ResolverCaller) Content(opts *bind.CallOpts, node [32]byte) ([32]byte, error) { + var ( + ret0 = new([32]byte) + ) + out := ret0 + err := _Resolver.contract.Call(opts, out, "content", node) + return *ret0, err +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_Resolver *ResolverSession) Content(node [32]byte) ([32]byte, error) { + return _Resolver.Contract.Content(&_Resolver.CallOpts, node) +} + +// Content is a free data retrieval call binding the contract method 0x2dff6941. +// +// Solidity: function content(node bytes32) constant returns(ret bytes32) +func (_Resolver *ResolverCallerSession) Content(node [32]byte) ([32]byte, error) { + return _Resolver.Contract.Content(&_Resolver.CallOpts, node) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_Resolver *ResolverTransactor) Has(opts *bind.TransactOpts, node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _Resolver.contract.Transact(opts, "has", node, kind) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_Resolver *ResolverSession) Has(node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _Resolver.Contract.Has(&_Resolver.TransactOpts, node, kind) +} + +// Has is a paid mutator transaction binding the contract method 0x41b9dc2b. +// +// Solidity: function has(node bytes32, kind bytes32) returns(bool) +func (_Resolver *ResolverTransactorSession) Has(node [32]byte, kind [32]byte) (*types.Transaction, error) { + return _Resolver.Contract.Has(&_Resolver.TransactOpts, node, kind) +} diff --git a/contracts/ens_private/contract/ens.sol b/contracts/ens_private/contract/ens.sol new file mode 100644 index 000000000..114cd7319 --- /dev/null +++ b/contracts/ens_private/contract/ens.sol @@ -0,0 +1,226 @@ +// Ethereum Name Service contracts by Nick Johnson +// +// To the extent possible under law, the person who associated CC0 with +// ENS contracts has waived all copyright and related or neighboring rights +// to ENS. +// +// You should have received a copy of the CC0 legalcode along with this +// work. If not, see . + +/** + * The ENS registry contract. + */ +contract ENS { + struct Record { + address owner; + address resolver; + } + + mapping(bytes32=>Record) records; + + // Logged when the owner of a node assigns a new owner to a subnode. + event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); + + // Logged when the owner of a node transfers ownership to a new account. + event Transfer(bytes32 indexed node, address owner); + + // Logged when the owner of a node changes the resolver for that node. + event NewResolver(bytes32 indexed node, address resolver); + + // Permits modifications only by the owner of the specified node. + modifier only_owner(bytes32 node) { + if(records[node].owner != msg.sender) throw; + _ + } + + /** + * Constructs a new ENS registrar, with the provided address as the owner of the root node. + */ + function ENS(address owner) { + records[0].owner = owner; + } + + /** + * Returns the address that owns the specified node. + */ + function owner(bytes32 node) constant returns (address) { + return records[node].owner; + } + + /** + * Returns the address of the resolver for the specified node. + */ + function resolver(bytes32 node) constant returns (address) { + return records[node].resolver; + } + + /** + * Transfers ownership of a node to a new address. May only be called by the current + * owner of the node. + * @param node The node to transfer ownership of. + * @param owner The address of the new owner. + */ + function setOwner(bytes32 node, address owner) only_owner(node) { + Transfer(node, owner); + records[node].owner = owner; + } + + /** + * Transfers ownership of a subnode sha3(node, label) to a new address. May only be + * called by the owner of the parent node. + * @param node The parent node. + * @param label The hash of the label specifying the subnode. + * @param owner The address of the new owner. + */ + function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) { + var subnode = sha3(node, label); + NewOwner(node, label, owner); + records[subnode].owner = owner; + } + + /** + * Sets the resolver address for the specified node. + * @param node The node to update. + * @param resolver The address of the resolver. + */ + function setResolver(bytes32 node, address resolver) only_owner(node) { + NewResolver(node, resolver); + records[node].resolver = resolver; + } +} + +/** + * A registrar that allocates subdomains to the first person to claim them. It also deploys + * a simple resolver contract and sets that as the default resolver on new names for + * convenience. + */ +contract FIFSRegistrar { + ENS ens; + PublicResolver defaultResolver; + bytes32 rootNode; + + /** + * Constructor. + * @param ensAddr The address of the ENS registry. + * @param node The node that this registrar administers. + */ + function FIFSRegistrar(address ensAddr, bytes32 node) { + ens = ENS(ensAddr); + defaultResolver = new PublicResolver(ensAddr); + rootNode = node; + } + + /** + * Register a name, or change the owner of an existing registration. + * @param subnode The hash of the label to register. + * @param owner The address of the new owner. + */ + function register(bytes32 subnode, address owner) { + var node = sha3(rootNode, subnode); + var currentOwner = ens.owner(node); + if(currentOwner != 0 && currentOwner != msg.sender) + throw; + + // Temporarily set ourselves as the owner + ens.setSubnodeOwner(rootNode, subnode, this); + // Set up the default resolver + ens.setResolver(node, defaultResolver); + // Set the owner to the real owner + ens.setOwner(node, owner); + } +} + +contract Resolver { + event AddrChanged(bytes32 indexed node, address a); + event ContentChanged(bytes32 indexed node, bytes32 hash); + + function has(bytes32 node, bytes32 kind) returns (bool); + function addr(bytes32 node) constant returns (address ret); + function content(bytes32 node) constant returns (bytes32 ret); +} + +/** + * A simple resolver anyone can use; only allows the owner of a node to set its + * address. + */ +contract PublicResolver is Resolver { + ENS ens; + mapping(bytes32=>address) addresses; + mapping(bytes32=>bytes32) contents; + + modifier only_owner(bytes32 node) { + if(ens.owner(node) != msg.sender) throw; + _ + } + + /** + * Constructor. + * @param ensAddr The ENS registrar contract. + */ + function PublicResolver(address ensAddr) { + ens = ENS(ensAddr); + } + + /** + * Fallback function. + */ + function() { + throw; + } + + /** + * Returns true if the specified node has the specified record type. + * @param node The ENS node to query. + * @param kind The record type name, as specified in EIP137. + * @return True if this resolver has a record of the provided type on the + * provided node. + */ + function has(bytes32 node, bytes32 kind) returns (bool) { + return (kind == "addr" && addresses[node] != 0) || + (kind == "content" && contents[node] != 0); + } + + /** + * Returns the address associated with an ENS node. + * @param node The ENS node to query. + * @return The associated address. + */ + function addr(bytes32 node) constant returns (address ret) { + ret = addresses[node]; + if(ret == 0) + throw; + } + + /** + * Returns the content hash associated with an ENS node. + * @param node The ENS node to query. + * @return The associated content hash. + */ + function content(bytes32 node) constant returns (bytes32 ret) { + ret = contents[node]; + if(ret == 0) + throw; + } + + /** + * Sets the address associated with an ENS node. + * May only be called by the owner of that node in the ENS registry. + * @param node The node to update. + * @param addr The address to set. + */ + function setAddr(bytes32 node, address addr) only_owner(node) { + addresses[node] = addr; + AddrChanged(node, addr); + } + + /** + * Sets the content hash associated with an ENS node. + * May only be called by the owner of that node in the ENS registry. + * @param node The node to update. + * @param hash The content hash to set. + */ + function setContent(bytes32 node, bytes32 hash) only_owner(node) { + contents[node] = hash; + ContentChanged(node, hash); + } +} diff --git a/contracts/ens_private/ens.go b/contracts/ens_private/ens.go new file mode 100644 index 000000000..c292a1714 --- /dev/null +++ b/contracts/ens_private/ens.go @@ -0,0 +1,183 @@ +// 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 . + +package ens + +//go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go + +import ( + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/contracts/ens/contract" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +var ( + MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b") + TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010") +) + +// swarm domain name registry and resolver +type ENS struct { + *contract.ENSSession + contractBackend bind.ContractBackend +} + +// NewENS creates a struct exposing convenient high-level operations for interacting with +// the Ethereum Name Service. +func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) { + ens, err := contract.NewENS(contractAddr, contractBackend) + if err != nil { + return nil, err + } + + return &ENS{ + &contract.ENSSession{ + Contract: ens, + TransactOpts: *transactOpts, + }, + contractBackend, + }, nil +} + +// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar. +func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (*ENS, error) { + // Deploy the ENS registry + ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend, transactOpts.From) + if err != nil { + return nil, err + } + + ens, err := NewENS(transactOpts, ensAddr, contractBackend) + if err != nil { + return nil, err + } + + // Deploy the registrar + regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{}) + if err != nil { + return nil, err + } + + // Set the registrar as owner of the ENS root + _, err = ens.SetOwner([32]byte{}, regAddr) + if err != nil { + return nil, err + } + + return ens, nil +} + +func ensParentNode(name string) (common.Hash, common.Hash) { + parts := strings.SplitN(name, ".", 2) + label := crypto.Keccak256Hash([]byte(parts[0])) + if len(parts) == 1 { + return [32]byte{}, label + } else { + parentNode, parentLabel := ensParentNode(parts[1]) + return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label + } +} + +func ensNode(name string) common.Hash { + parentNode, parentLabel := ensParentNode(name) + return crypto.Keccak256Hash(parentNode[:], parentLabel[:]) +} + +func (self *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) { + resolverAddr, err := self.Resolver(node) + if err != nil { + return nil, err + } + + resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend) + if err != nil { + return nil, err + } + + return &contract.PublicResolverSession{ + Contract: resolver, + TransactOpts: self.TransactOpts, + }, nil +} + +func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) { + registrarAddr, err := self.Owner(node) + if err != nil { + return nil, err + } + + registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend) + if err != nil { + return nil, err + } + + return &contract.FIFSRegistrarSession{ + Contract: registrar, + TransactOpts: self.TransactOpts, + }, nil +} + +// Resolve is a non-transactional call that returns the content hash associated with a name. +func (self *ENS) Resolve(name string) (common.Hash, error) { + node := ensNode(name) + + resolver, err := self.getResolver(node) + if err != nil { + return common.Hash{}, err + } + + ret, err := resolver.Content(node) + if err != nil { + return common.Hash{}, err + } + + return common.BytesToHash(ret[:]), nil +} + +// Register registers a new domain name for the caller, making them the owner of the new name. +// Only works if the registrar for the parent domain implements the FIFS registrar protocol. +func (self *ENS) Register(name string) (*types.Transaction, error) { + parentNode, label := ensParentNode(name) + + registrar, err := self.getRegistrar(parentNode) + if err != nil { + return nil, err + } + + opts := self.TransactOpts + opts.GasLimit = big.NewInt(200000) + return registrar.Contract.Register(&opts, label, self.TransactOpts.From) +} + +// SetContentHash sets the content hash associated with a name. Only works if the caller +// owns the name, and the associated resolver implements a `setContent` function. +func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) { + node := ensNode(name) + + resolver, err := self.getResolver(node) + if err != nil { + return nil, err + } + + opts := self.TransactOpts + opts.GasLimit = big.NewInt(200000) + return resolver.Contract.SetContent(&opts, node, hash) +} diff --git a/contracts/ens_private/ens_test.go b/contracts/ens_private/ens_test.go new file mode 100644 index 000000000..2a6783357 --- /dev/null +++ b/contracts/ens_private/ens_test.go @@ -0,0 +1,72 @@ +// 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 . + +package ens + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/crypto" +) + +var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + name = "my name on ENS" + hash = crypto.Keccak256Hash([]byte("my content")) + addr = crypto.PubkeyToAddress(key.PublicKey) +) + +func TestENS(t *testing.T) { + contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}) + transactOpts := bind.NewKeyedTransactor(key) + // Workaround for bug estimating gas in the call to Register + transactOpts.GasLimit = big.NewInt(1000000) + privateFrom := "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=" + privateFor := make([]string, 1) + privateFor[0] = "ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc=" + transactOpts.PrivateFrom = privateFrom + transactOpts.PrivateFor = privateFor + + ens, err := DeployENS(transactOpts, contractBackend) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + contractBackend.Commit() + + _, err = ens.Register(name) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + contractBackend.Commit() + + _, err = ens.SetContentHash(name, hash) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + contractBackend.Commit() + + vhost, err := ens.Resolve(name) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if vhost != hash { + t.Fatalf("resolve error, expected %v, got %v", hash.Hex(), vhost.Hex()) + } +} diff --git a/eth/bind.go b/eth/bind.go index d09977dbc..13f3cf980 100644 --- a/eth/bind.go +++ b/eth/bind.go @@ -18,6 +18,7 @@ package eth import ( "context" + "errors" "math/big" "github.com/ethereum/go-ethereum" @@ -25,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -136,3 +138,30 @@ func (b *ContractBackend) SendTransaction(ctx context.Context, tx *types.Transac _, err := b.txapi.SendRawTransaction(ctx, raw) return err } + +func (b *ContractBackend) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { + if len(privateFor) == 0 { + return nil, errors.New("need at least one private for") + } + tx := new(types.Transaction) + if err := rlp.DecodeBytes(encodedTx, tx); err != nil { + return nil, err + } + + if private.P == nil { + return nil, errors.New("constellation not set up") + } + data, err := private.P.Send(tx.Data(), privateFrom, privateFor) + if err != nil { + return nil, err + } + + tx.SetPrivate() + tx.SetData(data) + newEncoded, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + + return hexutil.Bytes(newEncoded), nil +} diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 7f73ab113..88468163d 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -476,6 +477,33 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) } +func (ec *Client) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { + if len(privateFor) == 0 { + return nil, errors.New("need at least one private for") + } + tx := new(types.Transaction) + if err := rlp.DecodeBytes(encodedTx, tx); err != nil { + return nil, err + } + + if private.P == nil { + return nil, errors.New("constellation not set up") + } + data, err := private.P.Send(tx.Data(), privateFrom, privateFor) + if err != nil { + return nil, err + } + + tx.SetPrivate() + tx.SetData(data) + newEncoded, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + + return hexutil.Bytes(newEncoded), nil +} + func toCallArg(msg ethereum.CallMsg) interface{} { arg := map[string]interface{}{ "from": msg.From, From 8c3dabb282691f2c5ec5d31cc0dafc698e729af6 Mon Sep 17 00:00:00 2001 From: apratt3377 Date: Wed, 12 Sep 2018 13:39:17 -0400 Subject: [PATCH 3/6] add comments and doc --- accounts/abi/bind/base.go | 2 ++ accounts/abi/bind/doc.md | 7 +++++++ contracts/ens_private/ens_test.go | 4 +++- eth/bind.go | 2 ++ ethclient/ethclient.go | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 accounts/abi/bind/doc.md diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 879f963b4..f0c404ca1 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -242,6 +242,8 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i return signedTx, nil } +// PreparePrivateTransaction replaces the payload data of the transaction with a +// commitment to turn it into a private tx. func (c *BoundContract) preparePrivateTransaction(ctx context.Context, tx *types.Transaction, privateFrom string, privateFor []string) (*types.Transaction, error) { raw, _ := rlp.EncodeToBytes(tx) diff --git a/accounts/abi/bind/doc.md b/accounts/abi/bind/doc.md new file mode 100644 index 000000000..6a4a7c477 --- /dev/null +++ b/accounts/abi/bind/doc.md @@ -0,0 +1,7 @@ +# Abigen with Quorum + +Abigen is a source code generator that converts quorum abi definitions into type-safe Go packages. In addition to the original capabilities provided by Ethereum described [ here ](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) Quorum abigen also supports deploying private transactions. + +PrivateFrom and PrivateFor fields have been added to the *bind.TransactOpts type, which allows users to specify the public keys of the Constellation identity used to send and receive transactions. + +When using the PrivateFrom and PrivateFor fields, the "PRIVATE_CONFIG" environment variable must be set to point to the running constellation node's .ipc file and this node much match the public key set in the PrivateFrom field. If not, deploying the private contract will fail. \ No newline at end of file diff --git a/contracts/ens_private/ens_test.go b/contracts/ens_private/ens_test.go index 2a6783357..763cba012 100644 --- a/contracts/ens_private/ens_test.go +++ b/contracts/ens_private/ens_test.go @@ -38,9 +38,11 @@ func TestENS(t *testing.T) { transactOpts := bind.NewKeyedTransactor(key) // Workaround for bug estimating gas in the call to Register transactOpts.GasLimit = big.NewInt(1000000) + //set privacy fields privateFrom := "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=" - privateFor := make([]string, 1) + privateFor := make([]string, 2) privateFor[0] = "ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc=" + privateFor[1] = "QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc=" transactOpts.PrivateFrom = privateFrom transactOpts.PrivateFor = privateFor diff --git a/eth/bind.go b/eth/bind.go index 13f3cf980..9e92fd442 100644 --- a/eth/bind.go +++ b/eth/bind.go @@ -139,6 +139,8 @@ func (b *ContractBackend) SendTransaction(ctx context.Context, tx *types.Transac return err } +// PreparePrivateTransaction sends the encoded raw transaction to Constellation, +// returning the encoded commitment transaction. func (b *ContractBackend) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { if len(privateFor) == 0 { return nil, errors.New("need at least one private for") diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 88468163d..5e8f6cfa8 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -477,6 +477,8 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) } +// PreparePrivateTransaction sends the encoded raw transaction to Constellation, +// returning the encoded commitment transaction. func (ec *Client) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { if len(privateFor) == 0 { return nil, errors.New("need at least one private for") From cce5cc42739bb43749e26564b4855a8793ab6ddc Mon Sep 17 00:00:00 2001 From: apratt3377 Date: Wed, 12 Sep 2018 14:39:17 -0400 Subject: [PATCH 4/6] fix comments --- accounts/abi/bind/backend.go | 3 ++- accounts/abi/bind/doc.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index cac3cefb1..939ce7d6c 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -89,7 +89,8 @@ type ContractTransactor interface { EstimateGas(ctx context.Context, call ethereum.CallMsg) (usedGas *big.Int, err error) // SendTransaction injects the transaction into the pending pool for execution. SendTransaction(ctx context.Context, tx *types.Transaction) error - + // PreparePrivateTransaction sends the encoded raw transaction to Constellation, + // returning the encoded commitment transaction. PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) } diff --git a/accounts/abi/bind/doc.md b/accounts/abi/bind/doc.md index 6a4a7c477..0479e5639 100644 --- a/accounts/abi/bind/doc.md +++ b/accounts/abi/bind/doc.md @@ -1,7 +1,7 @@ # Abigen with Quorum -Abigen is a source code generator that converts quorum abi definitions into type-safe Go packages. In addition to the original capabilities provided by Ethereum described [ here ](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) Quorum abigen also supports deploying private transactions. +Abigen is a source code generator that converts quorum abi definitions into type-safe Go packages. In addition to the original capabilities provided by Ethereum described [here](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) Quorum abigen also supports deploying private transactions. -PrivateFrom and PrivateFor fields have been added to the *bind.TransactOpts type, which allows users to specify the public keys of the Constellation identity used to send and receive transactions. +PrivateFrom and PrivateFor fields have been added to the *bind.TransactOpts type which allows users to specify the public keys of the Constellation identity used to send and receive transactions. When using the PrivateFrom and PrivateFor fields, the "PRIVATE_CONFIG" environment variable must be set to point to the running constellation node's .ipc file and this node much match the public key set in the PrivateFrom field. If not, deploying the private contract will fail. \ No newline at end of file From 513c8c4720adead8104d2dce5c66a0c130de43d9 Mon Sep 17 00:00:00 2001 From: apratt3377 Date: Wed, 12 Sep 2018 14:40:26 -0400 Subject: [PATCH 5/6] add comments --- accounts/abi/bind/backends/simulated.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index b761a0304..af81e0bfd 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -289,6 +289,8 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa return nil } +// PreparePrivateTransaction replaces the payload data of the transaction with a +// commitment to turn it into a private tx. func (b *SimulatedBackend) PreparePrivateTransaction(ctx context.Context, encodedTx hexutil.Bytes, privateFrom string, privateFor []string) (hexutil.Bytes, error) { if len(privateFor) == 0 { return nil, errors.New("need at least one private for") From d11276fbc11ba564f2ecf96bdb0d98c817be8200 Mon Sep 17 00:00:00 2001 From: zzy96 Date: Wed, 24 Oct 2018 16:44:59 +0800 Subject: [PATCH 6/6] private abigen merged --- contracts/ens_private/contract/ens.go | 1076 +++++++++++++++++++++++- contracts/ens_private/contract/ens.sol | 4 +- contracts/ens_private/ens.go | 7 +- contracts/ens_private/ens_test.go | 2 +- eth/bind.go | 9 +- 5 files changed, 1049 insertions(+), 49 deletions(-) diff --git a/contracts/ens_private/contract/ens.go b/contracts/ens_private/contract/ens.go index aca16de50..cc7b24103 100644 --- a/contracts/ens_private/contract/ens.go +++ b/contracts/ens_private/contract/ens.go @@ -1,22 +1,24 @@ -// This file is an automatically generated Go binding. Do not modify as any -// change will likely be lost upon the next re-generation! +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. package contract import ( "strings" + ethereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" ) // ENSABI is the input ABI used to generate the binding from. -const ENSABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"label","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"inputs":[{"name":"owner","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"resolver","type":"address"}],"name":"NewResolver","type":"event"}]` +const ENSABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"resolver\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"label\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setSubnodeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setResolver\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"NewResolver\",\"type\":\"event\"}]" // ENSBin is the compiled bytecode used for deploying new contracts. -const ENSBin = `0x606060405260405160208061032683395060806040525160008080526020527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58054600160a060020a03191682179055506102c88061005e6000396000f3606060405260e060020a60003504630178b8bf811461004757806302571be31461006e57806306ab5923146100915780631896f70a146100c85780635b0fc9c3146100fc575b005b610130600435600081815260208190526040902060010154600160a060020a03165b919050565b610130600435600081815260208190526040902054600160a060020a0316610069565b6100456004356024356044356000838152602081905260408120548490600160a060020a0390811633919091161461014d57610002565b6100456004356024356000828152602081905260409020548290600160a060020a039081163391909116146101e757610002565b6100456004356024356000828152602081905260409020548290600160a060020a0390811633919091161461025957610002565b60408051600160a060020a03929092168252519081900360200190f35b60408051868152602081810187905282519182900383018220600160a060020a03871683529251929450869288927fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8292908290030190a382600060005060008460001916815260200190815260200160002060005060000160006101000a815481600160a060020a03021916908302179055505050505050565b60408051600160a060020a0384168152905184917f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0919081900360200190a2506000828152602081905260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916821790555050565b60408051600160a060020a0384168152905184917fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266919081900360200190a2506000828152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff191682179055505056` +const ENSBin = `0x608060405234801561001057600080fd5b50604051602080610409833981016040525160008080526020527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58054600160a060020a03909216600160a060020a0319909216919091179055610390806100796000396000f30060806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630178b8bf811461007157806302571be3146100a557806306ab5923146100bd5780631896f70a146100e65780635b0fc9c31461010a575b600080fd5b34801561007d57600080fd5b5061008960043561012e565b60408051600160a060020a039092168252519081900360200190f35b3480156100b157600080fd5b5061008960043561014c565b3480156100c957600080fd5b506100e4600435602435600160a060020a0360443516610167565b005b3480156100f257600080fd5b506100e4600435600160a060020a0360243516610221565b34801561011657600080fd5b506100e4600435600160a060020a03602435166102c4565b600090815260208190526040902060010154600160a060020a031690565b600090815260208190526040902054600160a060020a031690565b6000838152602081905260408120548490600160a060020a0316331461018c57600080fd5b60408051868152602080820187905282519182900383018220600160a060020a03871683529251929450869288927fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8292908290030190a3506000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555050565b6000828152602081905260409020548290600160a060020a0316331461024657600080fd5b60408051600160a060020a0384168152905184917f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0919081900360200190a250600091825260208290526040909120600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b6000828152602081905260409020548290600160a060020a031633146102e957600080fd5b60408051600160a060020a0384168152905184917fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266919081900360200190a250600091825260208290526040909120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039092169190911790555600a165627a7a72305820df4aac84ae1b2457acdbef94dbcf9e82967d538dc402aa754b2cddc657b9dee40029` // DeployENS deploys a new Ethereum contract, binding an instance of ENS to it. func DeployENS(auth *bind.TransactOpts, backend bind.ContractBackend, owner common.Address) (common.Address, *types.Transaction, *ENS, error) { @@ -28,13 +30,14 @@ func DeployENS(auth *bind.TransactOpts, backend bind.ContractBackend, owner comm if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}}, nil + return address, tx, &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil } // ENS is an auto generated Go binding around an Ethereum contract. type ENS struct { ENSCaller // Read-only binding to the contract ENSTransactor // Write-only binding to the contract + ENSFilterer // Log filterer for contract events } // ENSCaller is an auto generated read-only Go binding around an Ethereum contract. @@ -47,6 +50,11 @@ type ENSTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } +// ENSFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ENSFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + // ENSSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. type ENSSession struct { @@ -86,16 +94,16 @@ type ENSTransactorRaw struct { // NewENS creates a new instance of ENS, bound to a specific deployed contract. func NewENS(address common.Address, backend bind.ContractBackend) (*ENS, error) { - contract, err := bindENS(address, backend, backend) + contract, err := bindENS(address, backend, backend, backend) if err != nil { return nil, err } - return &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}}, nil + return &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil } // NewENSCaller creates a new read-only instance of ENS, bound to a specific deployed contract. func NewENSCaller(address common.Address, caller bind.ContractCaller) (*ENSCaller, error) { - contract, err := bindENS(address, caller, nil) + contract, err := bindENS(address, caller, nil, nil) if err != nil { return nil, err } @@ -104,20 +112,29 @@ func NewENSCaller(address common.Address, caller bind.ContractCaller) (*ENSCalle // NewENSTransactor creates a new write-only instance of ENS, bound to a specific deployed contract. func NewENSTransactor(address common.Address, transactor bind.ContractTransactor) (*ENSTransactor, error) { - contract, err := bindENS(address, nil, transactor) + contract, err := bindENS(address, nil, transactor, nil) if err != nil { return nil, err } return &ENSTransactor{contract: contract}, nil } +// NewENSFilterer creates a new log filterer instance of ENS, bound to a specific deployed contract. +func NewENSFilterer(address common.Address, filterer bind.ContractFilterer) (*ENSFilterer, error) { + contract, err := bindENS(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ENSFilterer{contract: contract}, nil +} + // bindENS binds a generic wrapper to an already deployed contract. -func bindENS(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { +func bindENS(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { parsed, err := abi.JSON(strings.NewReader(ENSABI)) if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor), nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -273,11 +290,419 @@ func (_ENS *ENSTransactorSession) SetSubnodeOwner(node [32]byte, label [32]byte, return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner) } +// ENSNewOwnerIterator is returned from FilterNewOwner and is used to iterate over the raw logs and unpacked data for NewOwner events raised by the ENS contract. +type ENSNewOwnerIterator struct { + Event *ENSNewOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ENSNewOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ENSNewOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ENSNewOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ENSNewOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ENSNewOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ENSNewOwner represents a NewOwner event raised by the ENS contract. +type ENSNewOwner struct { + Node [32]byte + Label [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewOwner is a free log retrieval operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82. +// +// Solidity: e NewOwner(node indexed bytes32, label indexed bytes32, owner address) +func (_ENS *ENSFilterer) FilterNewOwner(opts *bind.FilterOpts, node [][32]byte, label [][32]byte) (*ENSNewOwnerIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + var labelRule []interface{} + for _, labelItem := range label { + labelRule = append(labelRule, labelItem) + } + + logs, sub, err := _ENS.contract.FilterLogs(opts, "NewOwner", nodeRule, labelRule) + if err != nil { + return nil, err + } + return &ENSNewOwnerIterator{contract: _ENS.contract, event: "NewOwner", logs: logs, sub: sub}, nil +} + +// WatchNewOwner is a free log subscription operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82. +// +// Solidity: e NewOwner(node indexed bytes32, label indexed bytes32, owner address) +func (_ENS *ENSFilterer) WatchNewOwner(opts *bind.WatchOpts, sink chan<- *ENSNewOwner, node [][32]byte, label [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + var labelRule []interface{} + for _, labelItem := range label { + labelRule = append(labelRule, labelItem) + } + + logs, sub, err := _ENS.contract.WatchLogs(opts, "NewOwner", nodeRule, labelRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ENSNewOwner) + if err := _ENS.contract.UnpackLog(event, "NewOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ENSNewResolverIterator is returned from FilterNewResolver and is used to iterate over the raw logs and unpacked data for NewResolver events raised by the ENS contract. +type ENSNewResolverIterator struct { + Event *ENSNewResolver // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ENSNewResolverIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ENSNewResolver) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ENSNewResolver) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ENSNewResolverIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ENSNewResolverIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ENSNewResolver represents a NewResolver event raised by the ENS contract. +type ENSNewResolver struct { + Node [32]byte + Resolver common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewResolver is a free log retrieval operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0. +// +// Solidity: e NewResolver(node indexed bytes32, resolver address) +func (_ENS *ENSFilterer) FilterNewResolver(opts *bind.FilterOpts, node [][32]byte) (*ENSNewResolverIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _ENS.contract.FilterLogs(opts, "NewResolver", nodeRule) + if err != nil { + return nil, err + } + return &ENSNewResolverIterator{contract: _ENS.contract, event: "NewResolver", logs: logs, sub: sub}, nil +} + +// WatchNewResolver is a free log subscription operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0. +// +// Solidity: e NewResolver(node indexed bytes32, resolver address) +func (_ENS *ENSFilterer) WatchNewResolver(opts *bind.WatchOpts, sink chan<- *ENSNewResolver, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _ENS.contract.WatchLogs(opts, "NewResolver", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ENSNewResolver) + if err := _ENS.contract.UnpackLog(event, "NewResolver", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ENSTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ENS contract. +type ENSTransferIterator struct { + Event *ENSTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ENSTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ENSTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ENSTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ENSTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ENSTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ENSTransfer represents a Transfer event raised by the ENS contract. +type ENSTransfer struct { + Node [32]byte + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266. +// +// Solidity: e Transfer(node indexed bytes32, owner address) +func (_ENS *ENSFilterer) FilterTransfer(opts *bind.FilterOpts, node [][32]byte) (*ENSTransferIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _ENS.contract.FilterLogs(opts, "Transfer", nodeRule) + if err != nil { + return nil, err + } + return &ENSTransferIterator{contract: _ENS.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266. +// +// Solidity: e Transfer(node indexed bytes32, owner address) +func (_ENS *ENSFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ENSTransfer, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _ENS.contract.WatchLogs(opts, "Transfer", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ENSTransfer) + if err := _ENS.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + // FIFSRegistrarABI is the input ABI used to generate the binding from. -const FIFSRegistrarABI = `[{"constant":false,"inputs":[{"name":"subnode","type":"bytes32"},{"name":"owner","type":"address"}],"name":"register","outputs":[],"type":"function"},{"inputs":[{"name":"ensAddr","type":"address"},{"name":"node","type":"bytes32"}],"type":"constructor"}]` +const FIFSRegistrarABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"subnode\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"},{\"name\":\"node\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]" // FIFSRegistrarBin is the compiled bytecode used for deploying new contracts. -const FIFSRegistrarBin = `0x6060604081815280610620833960a090525160805160008054600160a060020a031916831790558160a0610367806100878339018082600160a060020a03168152602001915050604051809103906000f0600160006101000a815481600160a060020a0302191690830217905550806002600050819055505050610232806103ee6000396000f3606060405260405160208061036783395060806040525160008054600160a060020a0319168217905550610330806100376000396000f36060604052361561004b5760e060020a60003504632dff694181146100535780633b3b57de1461007557806341b9dc2b146100a0578063c3d014d614610139578063d5fa2b00146101b2575b61022b610002565b61022d6004356000818152600260205260408120549081141561027057610002565b61023f600435600081815260016020526040812054600160a060020a03169081141561027057610002565b61025c60043560243560007f6164647200000000000000000000000000000000000000000000000000000000821480156100f05750600083815260016020526040812054600160a060020a031614155b8061013257507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610132575060008381526002602052604081205414155b9392505050565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a031691909114905061027557610002565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a03169190911490506102c157610002565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b919050565b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916851790558151600160a060020a0385168152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a250505056606060405260e060020a6000350463d22057a9811461001b575b005b61001960043560243560025460408051918252602082810185905260008054835194859003840185207f02571be300000000000000000000000000000000000000000000000000000000865260048601819052935193949193600160a060020a03909116926302571be39260248181019391829003018187876161da5a03f11561000257505060405151915050600160a060020a0381166000148015906100d4575033600160a060020a031681600160a060020a031614155b156100de57610002565b60408051600080546002547f06ab592300000000000000000000000000000000000000000000000000000000845260048401526024830188905230600160a060020a03908116604485015293519316926306ab5923926064818101939291829003018183876161da5a03f11561000257505060008054600154604080517f1896f70a00000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a0392831660248201529051929091169350631896f70a926044828101939192829003018183876161da5a03f11561000257505060008054604080517f5b0fc9c300000000000000000000000000000000000000000000000000000000815260048101879052600160a060020a0388811660248301529151929091169350635b0fc9c3926044828101939192829003018183876161da5a03f115610002575050505050505056` +const FIFSRegistrarBin = `0x608060405234801561001057600080fd5b5060405160408061087283398101604052805160209091015160008054600160a060020a031916600160a060020a0384161790558161004d6100a4565b600160a060020a03909116815260405190819003602001906000f08015801561007a573d6000803e3d6000fd5b5060018054600160a060020a031916600160a060020a0392909216919091179055600255506100b4565b6040516104ac806103c683390190565b610303806100c36000396000f3006080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d22057a98114610045575b600080fd5b34801561005157600080fd5b50610069600435600160a060020a036024351661006b565b005b60025460408051918252602080830185905281519283900382018320600080547f02571be300000000000000000000000000000000000000000000000000000000865260048601839052935191949093600160a060020a0316926302571be39260248084019382900301818787803b1580156100e657600080fd5b505af11580156100fa573d6000803e3d6000fd5b505050506040513d602081101561011057600080fd5b50519050600160a060020a038116158015906101355750600160a060020a0381163314155b1561013f57600080fd5b60008054600254604080517f06ab592300000000000000000000000000000000000000000000000000000000815260048101929092526024820188905230604483015251600160a060020a03909216926306ab59239260648084019382900301818387803b1580156101b057600080fd5b505af11580156101c4573d6000803e3d6000fd5b505060008054600154604080517f1896f70a00000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a0392831660248201529051919092169450631896f70a93506044808301939282900301818387803b15801561023657600080fd5b505af115801561024a573d6000803e3d6000fd5b505060008054604080517f5b0fc9c300000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a0389811660248301529151919092169450635b0fc9c393506044808301939282900301818387803b1580156102b957600080fd5b505af11580156102cd573d6000803e3d6000fd5b50505050505050505600a165627a7a72305820ae55b028e60774a969020d5f3463d7dc2cb5315c985ebef83412a1e0a1d386c40029608060405234801561001057600080fd5b506040516020806104ac833981016040525160008054600160a060020a03909216600160a060020a031990921691909117905561045a806100526000396000f30060806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632dff6941811461007e5780633b3b57de146100a857806341b9dc2b146100dc578063c3d014d61461010b578063d5fa2b0014610128575b34801561007857600080fd5b50600080fd5b34801561008a57600080fd5b5061009660043561014c565b60408051918252519081900360200190f35b3480156100b457600080fd5b506100c060043561016c565b60408051600160a060020a039092168252519081900360200190f35b3480156100e857600080fd5b506100f7600435602435610190565b604080519115158252519081900360200190f35b34801561011757600080fd5b50610126600435602435610220565b005b34801561013457600080fd5b50610126600435600160a060020a0360243516610314565b60008181526002602052604090205480151561016757600080fd5b919050565b600081815260016020526040902054600160a060020a031680151561016757600080fd5b60007f6164647200000000000000000000000000000000000000000000000000000000821480156101d75750600083815260016020526040902054600160a060020a031615155b8061021957507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610219575060008381526002602052604090205415155b9392505050565b60008054604080517f02571be300000000000000000000000000000000000000000000000000000000815260048101869052905185933393600160a060020a0316926302571be39260248083019360209383900390910190829087803b15801561028957600080fd5b505af115801561029d573d6000803e3d6000fd5b505050506040513d60208110156102b357600080fd5b5051600160a060020a0316146102c857600080fd5b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b60008054604080517f02571be300000000000000000000000000000000000000000000000000000000815260048101869052905185933393600160a060020a0316926302571be39260248083019360209383900390910190829087803b15801561037d57600080fd5b505af1158015610391573d6000803e3d6000fd5b505050506040513d60208110156103a757600080fd5b5051600160a060020a0316146103bc57600080fd5b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a25050505600a165627a7a72305820e828d8c34d5c1fa2d5ef031c0663cb888b98ce4d9d76f94612232dbd8499833c0029` // DeployFIFSRegistrar deploys a new Ethereum contract, binding an instance of FIFSRegistrar to it. func DeployFIFSRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address, node [32]byte) (common.Address, *types.Transaction, *FIFSRegistrar, error) { @@ -289,13 +714,14 @@ func DeployFIFSRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}}, nil + return address, tx, &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil } // FIFSRegistrar is an auto generated Go binding around an Ethereum contract. type FIFSRegistrar struct { FIFSRegistrarCaller // Read-only binding to the contract FIFSRegistrarTransactor // Write-only binding to the contract + FIFSRegistrarFilterer // Log filterer for contract events } // FIFSRegistrarCaller is an auto generated read-only Go binding around an Ethereum contract. @@ -308,6 +734,11 @@ type FIFSRegistrarTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } +// FIFSRegistrarFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type FIFSRegistrarFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + // FIFSRegistrarSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. type FIFSRegistrarSession struct { @@ -347,16 +778,16 @@ type FIFSRegistrarTransactorRaw struct { // NewFIFSRegistrar creates a new instance of FIFSRegistrar, bound to a specific deployed contract. func NewFIFSRegistrar(address common.Address, backend bind.ContractBackend) (*FIFSRegistrar, error) { - contract, err := bindFIFSRegistrar(address, backend, backend) + contract, err := bindFIFSRegistrar(address, backend, backend, backend) if err != nil { return nil, err } - return &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}}, nil + return &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil } // NewFIFSRegistrarCaller creates a new read-only instance of FIFSRegistrar, bound to a specific deployed contract. func NewFIFSRegistrarCaller(address common.Address, caller bind.ContractCaller) (*FIFSRegistrarCaller, error) { - contract, err := bindFIFSRegistrar(address, caller, nil) + contract, err := bindFIFSRegistrar(address, caller, nil, nil) if err != nil { return nil, err } @@ -365,20 +796,29 @@ func NewFIFSRegistrarCaller(address common.Address, caller bind.ContractCaller) // NewFIFSRegistrarTransactor creates a new write-only instance of FIFSRegistrar, bound to a specific deployed contract. func NewFIFSRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*FIFSRegistrarTransactor, error) { - contract, err := bindFIFSRegistrar(address, nil, transactor) + contract, err := bindFIFSRegistrar(address, nil, transactor, nil) if err != nil { return nil, err } return &FIFSRegistrarTransactor{contract: contract}, nil } +// NewFIFSRegistrarFilterer creates a new log filterer instance of FIFSRegistrar, bound to a specific deployed contract. +func NewFIFSRegistrarFilterer(address common.Address, filterer bind.ContractFilterer) (*FIFSRegistrarFilterer, error) { + contract, err := bindFIFSRegistrar(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &FIFSRegistrarFilterer{contract: contract}, nil +} + // bindFIFSRegistrar binds a generic wrapper to an already deployed contract. -func bindFIFSRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { +func bindFIFSRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI)) if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor), nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -441,10 +881,10 @@ func (_FIFSRegistrar *FIFSRegistrarTransactorSession) Register(subnode [32]byte, } // PublicResolverABI is the input ABI used to generate the binding from. -const PublicResolverABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"content","outputs":[{"name":"ret","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"addr","outputs":[{"name":"ret","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"kind","type":"bytes32"}],"name":"has","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"hash","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"addr","type":"address"}],"name":"setAddr","outputs":[],"type":"function"},{"inputs":[{"name":"ensAddr","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes32"}],"name":"ContentChanged","type":"event"}]` +const PublicResolverABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"content\",\"outputs\":[{\"name\":\"ret\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"ret\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"kind\",\"type\":\"bytes32\"}],\"name\":\"has\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"setContent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"ContentChanged\",\"type\":\"event\"}]" // PublicResolverBin is the compiled bytecode used for deploying new contracts. -const PublicResolverBin = `0x606060405260405160208061036783395060806040525160008054600160a060020a0319168217905550610330806100376000396000f36060604052361561004b5760e060020a60003504632dff694181146100535780633b3b57de1461007557806341b9dc2b146100a0578063c3d014d614610139578063d5fa2b00146101b2575b61022b610002565b61022d6004356000818152600260205260408120549081141561027057610002565b61023f600435600081815260016020526040812054600160a060020a03169081141561027057610002565b61025c60043560243560007f6164647200000000000000000000000000000000000000000000000000000000821480156100f05750600083815260016020526040812054600160a060020a031614155b8061013257507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610132575060008381526002602052604081205414155b9392505050565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a031691909114905061027557610002565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a03169190911490506102c157610002565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b919050565b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916851790558151600160a060020a0385168152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a250505056` +const PublicResolverBin = `0x608060405234801561001057600080fd5b506040516020806104ac833981016040525160008054600160a060020a03909216600160a060020a031990921691909117905561045a806100526000396000f30060806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632dff6941811461007e5780633b3b57de146100a857806341b9dc2b146100dc578063c3d014d61461010b578063d5fa2b0014610128575b34801561007857600080fd5b50600080fd5b34801561008a57600080fd5b5061009660043561014c565b60408051918252519081900360200190f35b3480156100b457600080fd5b506100c060043561016c565b60408051600160a060020a039092168252519081900360200190f35b3480156100e857600080fd5b506100f7600435602435610190565b604080519115158252519081900360200190f35b34801561011757600080fd5b50610126600435602435610220565b005b34801561013457600080fd5b50610126600435600160a060020a0360243516610314565b60008181526002602052604090205480151561016757600080fd5b919050565b600081815260016020526040902054600160a060020a031680151561016757600080fd5b60007f6164647200000000000000000000000000000000000000000000000000000000821480156101d75750600083815260016020526040902054600160a060020a031615155b8061021957507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610219575060008381526002602052604090205415155b9392505050565b60008054604080517f02571be300000000000000000000000000000000000000000000000000000000815260048101869052905185933393600160a060020a0316926302571be39260248083019360209383900390910190829087803b15801561028957600080fd5b505af115801561029d573d6000803e3d6000fd5b505050506040513d60208110156102b357600080fd5b5051600160a060020a0316146102c857600080fd5b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b60008054604080517f02571be300000000000000000000000000000000000000000000000000000000815260048101869052905185933393600160a060020a0316926302571be39260248083019360209383900390910190829087803b15801561037d57600080fd5b505af1158015610391573d6000803e3d6000fd5b505050506040513d60208110156103a757600080fd5b5051600160a060020a0316146103bc57600080fd5b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a25050505600a165627a7a72305820e828d8c34d5c1fa2d5ef031c0663cb888b98ce4d9d76f94612232dbd8499833c0029` // DeployPublicResolver deploys a new Ethereum contract, binding an instance of PublicResolver to it. func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address) (common.Address, *types.Transaction, *PublicResolver, error) { @@ -456,13 +896,14 @@ func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}}, nil + return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil } // PublicResolver is an auto generated Go binding around an Ethereum contract. type PublicResolver struct { PublicResolverCaller // Read-only binding to the contract PublicResolverTransactor // Write-only binding to the contract + PublicResolverFilterer // Log filterer for contract events } // PublicResolverCaller is an auto generated read-only Go binding around an Ethereum contract. @@ -475,6 +916,11 @@ type PublicResolverTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } +// PublicResolverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PublicResolverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + // PublicResolverSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. type PublicResolverSession struct { @@ -514,16 +960,16 @@ type PublicResolverTransactorRaw struct { // NewPublicResolver creates a new instance of PublicResolver, bound to a specific deployed contract. func NewPublicResolver(address common.Address, backend bind.ContractBackend) (*PublicResolver, error) { - contract, err := bindPublicResolver(address, backend, backend) + contract, err := bindPublicResolver(address, backend, backend, backend) if err != nil { return nil, err } - return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}}, nil + return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil } // NewPublicResolverCaller creates a new read-only instance of PublicResolver, bound to a specific deployed contract. func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) (*PublicResolverCaller, error) { - contract, err := bindPublicResolver(address, caller, nil) + contract, err := bindPublicResolver(address, caller, nil, nil) if err != nil { return nil, err } @@ -532,20 +978,29 @@ func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) // NewPublicResolverTransactor creates a new write-only instance of PublicResolver, bound to a specific deployed contract. func NewPublicResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*PublicResolverTransactor, error) { - contract, err := bindPublicResolver(address, nil, transactor) + contract, err := bindPublicResolver(address, nil, transactor, nil) if err != nil { return nil, err } return &PublicResolverTransactor{contract: contract}, nil } +// NewPublicResolverFilterer creates a new log filterer instance of PublicResolver, bound to a specific deployed contract. +func NewPublicResolverFilterer(address common.Address, filterer bind.ContractFilterer) (*PublicResolverFilterer, error) { + contract, err := bindPublicResolver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PublicResolverFilterer{contract: contract}, nil +} + // bindPublicResolver binds a generic wrapper to an already deployed contract. -func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { +func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { parsed, err := abi.JSON(strings.NewReader(PublicResolverABI)) if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor), nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -701,8 +1156,274 @@ func (_PublicResolver *PublicResolverTransactorSession) SetContent(node [32]byte return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash) } +// PublicResolverAddrChangedIterator is returned from FilterAddrChanged and is used to iterate over the raw logs and unpacked data for AddrChanged events raised by the PublicResolver contract. +type PublicResolverAddrChangedIterator struct { + Event *PublicResolverAddrChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PublicResolverAddrChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PublicResolverAddrChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PublicResolverAddrChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PublicResolverAddrChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PublicResolverAddrChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PublicResolverAddrChanged represents a AddrChanged event raised by the PublicResolver contract. +type PublicResolverAddrChanged struct { + Node [32]byte + A common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddrChanged is a free log retrieval operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. +// +// Solidity: e AddrChanged(node indexed bytes32, a address) +func (_PublicResolver *PublicResolverFilterer) FilterAddrChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverAddrChangedIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "AddrChanged", nodeRule) + if err != nil { + return nil, err + } + return &PublicResolverAddrChangedIterator{contract: _PublicResolver.contract, event: "AddrChanged", logs: logs, sub: sub}, nil +} + +// WatchAddrChanged is a free log subscription operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. +// +// Solidity: e AddrChanged(node indexed bytes32, a address) +func (_PublicResolver *PublicResolverFilterer) WatchAddrChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverAddrChanged, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "AddrChanged", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PublicResolverAddrChanged) + if err := _PublicResolver.contract.UnpackLog(event, "AddrChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// PublicResolverContentChangedIterator is returned from FilterContentChanged and is used to iterate over the raw logs and unpacked data for ContentChanged events raised by the PublicResolver contract. +type PublicResolverContentChangedIterator struct { + Event *PublicResolverContentChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PublicResolverContentChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PublicResolverContentChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PublicResolverContentChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PublicResolverContentChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PublicResolverContentChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PublicResolverContentChanged represents a ContentChanged event raised by the PublicResolver contract. +type PublicResolverContentChanged struct { + Node [32]byte + Hash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterContentChanged is a free log retrieval operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. +// +// Solidity: e ContentChanged(node indexed bytes32, hash bytes32) +func (_PublicResolver *PublicResolverFilterer) FilterContentChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverContentChangedIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ContentChanged", nodeRule) + if err != nil { + return nil, err + } + return &PublicResolverContentChangedIterator{contract: _PublicResolver.contract, event: "ContentChanged", logs: logs, sub: sub}, nil +} + +// WatchContentChanged is a free log subscription operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. +// +// Solidity: e ContentChanged(node indexed bytes32, hash bytes32) +func (_PublicResolver *PublicResolverFilterer) WatchContentChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverContentChanged, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ContentChanged", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PublicResolverContentChanged) + if err := _PublicResolver.contract.UnpackLog(event, "ContentChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + // ResolverABI is the input ABI used to generate the binding from. -const ResolverABI = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"content","outputs":[{"name":"ret","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"addr","outputs":[{"name":"ret","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"kind","type":"bytes32"}],"name":"has","outputs":[{"name":"","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes32"}],"name":"ContentChanged","type":"event"}]` +const ResolverABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"content\",\"outputs\":[{\"name\":\"ret\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"ret\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"kind\",\"type\":\"bytes32\"}],\"name\":\"has\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"ContentChanged\",\"type\":\"event\"}]" // ResolverBin is the compiled bytecode used for deploying new contracts. const ResolverBin = `0x` @@ -717,13 +1438,14 @@ func DeployResolver(auth *bind.TransactOpts, backend bind.ContractBackend) (comm if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}}, nil + return address, tx, &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}, ResolverFilterer: ResolverFilterer{contract: contract}}, nil } // Resolver is an auto generated Go binding around an Ethereum contract. type Resolver struct { ResolverCaller // Read-only binding to the contract ResolverTransactor // Write-only binding to the contract + ResolverFilterer // Log filterer for contract events } // ResolverCaller is an auto generated read-only Go binding around an Ethereum contract. @@ -736,6 +1458,11 @@ type ResolverTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } +// ResolverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ResolverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + // ResolverSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. type ResolverSession struct { @@ -775,16 +1502,16 @@ type ResolverTransactorRaw struct { // NewResolver creates a new instance of Resolver, bound to a specific deployed contract. func NewResolver(address common.Address, backend bind.ContractBackend) (*Resolver, error) { - contract, err := bindResolver(address, backend, backend) + contract, err := bindResolver(address, backend, backend, backend) if err != nil { return nil, err } - return &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}}, nil + return &Resolver{ResolverCaller: ResolverCaller{contract: contract}, ResolverTransactor: ResolverTransactor{contract: contract}, ResolverFilterer: ResolverFilterer{contract: contract}}, nil } // NewResolverCaller creates a new read-only instance of Resolver, bound to a specific deployed contract. func NewResolverCaller(address common.Address, caller bind.ContractCaller) (*ResolverCaller, error) { - contract, err := bindResolver(address, caller, nil) + contract, err := bindResolver(address, caller, nil, nil) if err != nil { return nil, err } @@ -793,20 +1520,29 @@ func NewResolverCaller(address common.Address, caller bind.ContractCaller) (*Res // NewResolverTransactor creates a new write-only instance of Resolver, bound to a specific deployed contract. func NewResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*ResolverTransactor, error) { - contract, err := bindResolver(address, nil, transactor) + contract, err := bindResolver(address, nil, transactor, nil) if err != nil { return nil, err } return &ResolverTransactor{contract: contract}, nil } +// NewResolverFilterer creates a new log filterer instance of Resolver, bound to a specific deployed contract. +func NewResolverFilterer(address common.Address, filterer bind.ContractFilterer) (*ResolverFilterer, error) { + contract, err := bindResolver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ResolverFilterer{contract: contract}, nil +} + // bindResolver binds a generic wrapper to an already deployed contract. -func bindResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) { +func bindResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { parsed, err := abi.JSON(strings.NewReader(ResolverABI)) if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor), nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -919,3 +1655,269 @@ func (_Resolver *ResolverSession) Has(node [32]byte, kind [32]byte) (*types.Tran func (_Resolver *ResolverTransactorSession) Has(node [32]byte, kind [32]byte) (*types.Transaction, error) { return _Resolver.Contract.Has(&_Resolver.TransactOpts, node, kind) } + +// ResolverAddrChangedIterator is returned from FilterAddrChanged and is used to iterate over the raw logs and unpacked data for AddrChanged events raised by the Resolver contract. +type ResolverAddrChangedIterator struct { + Event *ResolverAddrChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ResolverAddrChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ResolverAddrChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ResolverAddrChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ResolverAddrChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ResolverAddrChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ResolverAddrChanged represents a AddrChanged event raised by the Resolver contract. +type ResolverAddrChanged struct { + Node [32]byte + A common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddrChanged is a free log retrieval operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. +// +// Solidity: e AddrChanged(node indexed bytes32, a address) +func (_Resolver *ResolverFilterer) FilterAddrChanged(opts *bind.FilterOpts, node [][32]byte) (*ResolverAddrChangedIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _Resolver.contract.FilterLogs(opts, "AddrChanged", nodeRule) + if err != nil { + return nil, err + } + return &ResolverAddrChangedIterator{contract: _Resolver.contract, event: "AddrChanged", logs: logs, sub: sub}, nil +} + +// WatchAddrChanged is a free log subscription operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2. +// +// Solidity: e AddrChanged(node indexed bytes32, a address) +func (_Resolver *ResolverFilterer) WatchAddrChanged(opts *bind.WatchOpts, sink chan<- *ResolverAddrChanged, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _Resolver.contract.WatchLogs(opts, "AddrChanged", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ResolverAddrChanged) + if err := _Resolver.contract.UnpackLog(event, "AddrChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ResolverContentChangedIterator is returned from FilterContentChanged and is used to iterate over the raw logs and unpacked data for ContentChanged events raised by the Resolver contract. +type ResolverContentChangedIterator struct { + Event *ResolverContentChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ResolverContentChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ResolverContentChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ResolverContentChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ResolverContentChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ResolverContentChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ResolverContentChanged represents a ContentChanged event raised by the Resolver contract. +type ResolverContentChanged struct { + Node [32]byte + Hash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterContentChanged is a free log retrieval operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. +// +// Solidity: e ContentChanged(node indexed bytes32, hash bytes32) +func (_Resolver *ResolverFilterer) FilterContentChanged(opts *bind.FilterOpts, node [][32]byte) (*ResolverContentChangedIterator, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _Resolver.contract.FilterLogs(opts, "ContentChanged", nodeRule) + if err != nil { + return nil, err + } + return &ResolverContentChangedIterator{contract: _Resolver.contract, event: "ContentChanged", logs: logs, sub: sub}, nil +} + +// WatchContentChanged is a free log subscription operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc. +// +// Solidity: e ContentChanged(node indexed bytes32, hash bytes32) +func (_Resolver *ResolverFilterer) WatchContentChanged(opts *bind.WatchOpts, sink chan<- *ResolverContentChanged, node [][32]byte) (event.Subscription, error) { + + var nodeRule []interface{} + for _, nodeItem := range node { + nodeRule = append(nodeRule, nodeItem) + } + + logs, sub, err := _Resolver.contract.WatchLogs(opts, "ContentChanged", nodeRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ResolverContentChanged) + if err := _Resolver.contract.UnpackLog(event, "ContentChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} diff --git a/contracts/ens_private/contract/ens.sol b/contracts/ens_private/contract/ens.sol index 114cd7319..21755ae84 100644 --- a/contracts/ens_private/contract/ens.sol +++ b/contracts/ens_private/contract/ens.sol @@ -30,7 +30,7 @@ contract ENS { // Permits modifications only by the owner of the specified node. modifier only_owner(bytes32 node) { if(records[node].owner != msg.sender) throw; - _ + _; } /** @@ -150,7 +150,7 @@ contract PublicResolver is Resolver { modifier only_owner(bytes32 node) { if(ens.owner(node) != msg.sender) throw; - _ + _; } /** diff --git a/contracts/ens_private/ens.go b/contracts/ens_private/ens.go index c292a1714..254eb1c08 100644 --- a/contracts/ens_private/ens.go +++ b/contracts/ens_private/ens.go @@ -19,12 +19,11 @@ package ens //go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go import ( - "math/big" "strings" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/ens/contract" + "github.com/ethereum/go-ethereum/contracts/ens_private/contract" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" ) @@ -163,7 +162,7 @@ func (self *ENS) Register(name string) (*types.Transaction, error) { } opts := self.TransactOpts - opts.GasLimit = big.NewInt(200000) + opts.GasLimit = 200000 return registrar.Contract.Register(&opts, label, self.TransactOpts.From) } @@ -178,6 +177,6 @@ func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transacti } opts := self.TransactOpts - opts.GasLimit = big.NewInt(200000) + opts.GasLimit = 200000 return resolver.Contract.SetContent(&opts, node, hash) } diff --git a/contracts/ens_private/ens_test.go b/contracts/ens_private/ens_test.go index 763cba012..895f2c158 100644 --- a/contracts/ens_private/ens_test.go +++ b/contracts/ens_private/ens_test.go @@ -37,7 +37,7 @@ func TestENS(t *testing.T) { contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}) transactOpts := bind.NewKeyedTransactor(key) // Workaround for bug estimating gas in the call to Register - transactOpts.GasLimit = big.NewInt(1000000) + transactOpts.GasLimit = 1000000 //set privacy fields privateFrom := "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=" privateFor := make([]string, 2) diff --git a/eth/bind.go b/eth/bind.go index 9e92fd442..e55aba060 100644 --- a/eth/bind.go +++ b/eth/bind.go @@ -85,9 +85,7 @@ func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs { To: msg.To, From: msg.From, Data: msg.Data, - } - if msg.Gas != nil { - args.Gas = hexutil.Big(*msg.Gas) + Gas: hexutil.Uint64(msg.Gas), } if msg.GasPrice != nil { args.GasPrice = hexutil.Big(*msg.GasPrice) @@ -118,7 +116,8 @@ func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Add // SuggestGasPrice implements bind.ContractTransactor retrieving the currently // suggested gas price to allow a timely execution of a transaction. func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { - return b.eapi.GasPrice(ctx) + price, error := b.eapi.GasPrice(ctx) + return price.ToInt(), error } // EstimateGasLimit implements bind.ContractTransactor triing to estimate the gas @@ -128,7 +127,7 @@ func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) // should provide a basis for setting a reasonable default. func (b *ContractBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (*big.Int, error) { out, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg)) - return out.ToInt(), err + return new(big.Int).SetUint64(uint64(out)), err } // SendTransaction implements bind.ContractTransactor injects the transaction