forked from cerc-io/plugeth
Merge pull request #16619 from kielbarry/contractsgolint
contracts/*: golint updates for this or self warning
This commit is contained in:
commit
85b3b1c8d6
@ -27,40 +27,40 @@ const Version = "1.0"
|
|||||||
|
|
||||||
var errNoChequebook = errors.New("no chequebook")
|
var errNoChequebook = errors.New("no chequebook")
|
||||||
|
|
||||||
type Api struct {
|
type API struct {
|
||||||
chequebookf func() *Chequebook
|
chequebookf func() *Chequebook
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApi(ch func() *Chequebook) *Api {
|
func NewAPI(ch func() *Chequebook) *API {
|
||||||
return &Api{ch}
|
return &API{ch}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) Balance() (string, error) {
|
func (a *API) Balance() (string, error) {
|
||||||
ch := self.chequebookf()
|
ch := a.chequebookf()
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return "", errNoChequebook
|
return "", errNoChequebook
|
||||||
}
|
}
|
||||||
return ch.Balance().String(), nil
|
return ch.Balance().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) Issue(beneficiary common.Address, amount *big.Int) (cheque *Cheque, err error) {
|
func (a *API) Issue(beneficiary common.Address, amount *big.Int) (cheque *Cheque, err error) {
|
||||||
ch := self.chequebookf()
|
ch := a.chequebookf()
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return nil, errNoChequebook
|
return nil, errNoChequebook
|
||||||
}
|
}
|
||||||
return ch.Issue(beneficiary, amount)
|
return ch.Issue(beneficiary, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) Cash(cheque *Cheque) (txhash string, err error) {
|
func (a *API) Cash(cheque *Cheque) (txhash string, err error) {
|
||||||
ch := self.chequebookf()
|
ch := a.chequebookf()
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return "", errNoChequebook
|
return "", errNoChequebook
|
||||||
}
|
}
|
||||||
return ch.Cash(cheque)
|
return ch.Cash(cheque)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) Deposit(amount *big.Int) (txhash string, err error) {
|
func (a *API) Deposit(amount *big.Int) (txhash string, err error) {
|
||||||
ch := self.chequebookf()
|
ch := a.chequebookf()
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return "", errNoChequebook
|
return "", errNoChequebook
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ type Cheque struct {
|
|||||||
Sig []byte // signature Sign(Keccak256(contract, beneficiary, amount), prvKey)
|
Sig []byte // signature Sign(Keccak256(contract, beneficiary, amount), prvKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Cheque) String() string {
|
func (ch *Cheque) String() string {
|
||||||
return fmt.Sprintf("contract: %s, beneficiary: %s, amount: %v, signature: %x", self.Contract.Hex(), self.Beneficiary.Hex(), self.Amount, self.Sig)
|
return fmt.Sprintf("contract: %s, beneficiary: %s, amount: %v, signature: %x", ch.Contract.Hex(), ch.Beneficiary.Hex(), ch.Amount, ch.Sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Params struct {
|
type Params struct {
|
||||||
@ -109,12 +109,12 @@ type Chequebook struct {
|
|||||||
log log.Logger // contextual logger with the contract address embedded
|
log log.Logger // contextual logger with the contract address embedded
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Chequebook) String() string {
|
func (cb *Chequebook) String() string {
|
||||||
return fmt.Sprintf("contract: %s, owner: %s, balance: %v, signer: %x", self.contractAddr.Hex(), self.owner.Hex(), self.balance, self.prvKey.PublicKey)
|
return fmt.Sprintf("contract: %s, owner: %s, balance: %v, signer: %x", cb.contractAddr.Hex(), cb.owner.Hex(), cb.balance, cb.prvKey.PublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChequebook creates a new Chequebook.
|
// NewChequebook creates a new Chequebook.
|
||||||
func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.PrivateKey, backend Backend) (self *Chequebook, err error) {
|
func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.PrivateKey, backend Backend) (*Chequebook, error) {
|
||||||
balance := new(big.Int)
|
balance := new(big.Int)
|
||||||
sent := make(map[common.Address]*big.Int)
|
sent := make(map[common.Address]*big.Int)
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.Priva
|
|||||||
TransactOpts: *transactOpts,
|
TransactOpts: *transactOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
self = &Chequebook{
|
cb := &Chequebook{
|
||||||
prvKey: prvKey,
|
prvKey: prvKey,
|
||||||
balance: balance,
|
balance: balance,
|
||||||
contractAddr: contractAddr,
|
contractAddr: contractAddr,
|
||||||
@ -140,42 +140,39 @@ func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.Priva
|
|||||||
session: session,
|
session: session,
|
||||||
log: log.New("contract", contractAddr),
|
log: log.New("contract", contractAddr),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contractAddr != common.Address{}) {
|
if (contractAddr != common.Address{}) {
|
||||||
self.setBalanceFromBlockChain()
|
cb.setBalanceFromBlockChain()
|
||||||
self.log.Trace("New chequebook initialised", "owner", self.owner, "balance", self.balance)
|
cb.log.Trace("New chequebook initialised", "owner", cb.owner, "balance", cb.balance)
|
||||||
}
|
}
|
||||||
return
|
return cb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Chequebook) setBalanceFromBlockChain() {
|
func (cb *Chequebook) setBalanceFromBlockChain() {
|
||||||
balance, err := self.backend.BalanceAt(context.TODO(), self.contractAddr, nil)
|
balance, err := cb.backend.BalanceAt(context.TODO(), cb.contractAddr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to retrieve chequebook balance", "err", err)
|
log.Error("Failed to retrieve chequebook balance", "err", err)
|
||||||
} else {
|
} else {
|
||||||
self.balance.Set(balance)
|
cb.balance.Set(balance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadChequebook loads a chequebook from disk (file path).
|
// LoadChequebook loads a chequebook from disk (file path).
|
||||||
func LoadChequebook(path string, prvKey *ecdsa.PrivateKey, backend Backend, checkBalance bool) (self *Chequebook, err error) {
|
func LoadChequebook(path string, prvKey *ecdsa.PrivateKey, backend Backend, checkBalance bool) (*Chequebook, error) {
|
||||||
var data []byte
|
data, err := ioutil.ReadFile(path)
|
||||||
data, err = ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self, _ = NewChequebook(path, common.Address{}, prvKey, backend)
|
|
||||||
|
|
||||||
err = json.Unmarshal(data, self)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cb, _ := NewChequebook(path, common.Address{}, prvKey, backend)
|
||||||
|
|
||||||
|
if err = json.Unmarshal(data, cb); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if checkBalance {
|
if checkBalance {
|
||||||
self.setBalanceFromBlockChain()
|
cb.setBalanceFromBlockChain()
|
||||||
}
|
}
|
||||||
log.Trace("Loaded chequebook from disk", "path", path)
|
log.Trace("Loaded chequebook from disk", "path", path)
|
||||||
|
|
||||||
return
|
return cb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// chequebookFile is the JSON representation of a chequebook.
|
// chequebookFile is the JSON representation of a chequebook.
|
||||||
@ -187,19 +184,19 @@ type chequebookFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON deserialises a chequebook.
|
// UnmarshalJSON deserialises a chequebook.
|
||||||
func (self *Chequebook) UnmarshalJSON(data []byte) error {
|
func (cb *Chequebook) UnmarshalJSON(data []byte) error {
|
||||||
var file chequebookFile
|
var file chequebookFile
|
||||||
err := json.Unmarshal(data, &file)
|
err := json.Unmarshal(data, &file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, ok := self.balance.SetString(file.Balance, 10)
|
_, ok := cb.balance.SetString(file.Balance, 10)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("cumulative amount sent: unable to convert string to big integer: %v", file.Balance)
|
return fmt.Errorf("cumulative amount sent: unable to convert string to big integer: %v", file.Balance)
|
||||||
}
|
}
|
||||||
self.contractAddr = common.HexToAddress(file.Contract)
|
cb.contractAddr = common.HexToAddress(file.Contract)
|
||||||
for addr, sent := range file.Sent {
|
for addr, sent := range file.Sent {
|
||||||
self.sent[common.HexToAddress(addr)], ok = new(big.Int).SetString(sent, 10)
|
cb.sent[common.HexToAddress(addr)], ok = new(big.Int).SetString(sent, 10)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("beneficiary %v cumulative amount sent: unable to convert string to big integer: %v", addr, sent)
|
return fmt.Errorf("beneficiary %v cumulative amount sent: unable to convert string to big integer: %v", addr, sent)
|
||||||
}
|
}
|
||||||
@ -208,14 +205,14 @@ func (self *Chequebook) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON serialises a chequebook.
|
// MarshalJSON serialises a chequebook.
|
||||||
func (self *Chequebook) MarshalJSON() ([]byte, error) {
|
func (cb *Chequebook) MarshalJSON() ([]byte, error) {
|
||||||
var file = &chequebookFile{
|
var file = &chequebookFile{
|
||||||
Balance: self.balance.String(),
|
Balance: cb.balance.String(),
|
||||||
Contract: self.contractAddr.Hex(),
|
Contract: cb.contractAddr.Hex(),
|
||||||
Owner: self.owner.Hex(),
|
Owner: cb.owner.Hex(),
|
||||||
Sent: make(map[string]string),
|
Sent: make(map[string]string),
|
||||||
}
|
}
|
||||||
for addr, sent := range self.sent {
|
for addr, sent := range cb.sent {
|
||||||
file.Sent[addr.Hex()] = sent.String()
|
file.Sent[addr.Hex()] = sent.String()
|
||||||
}
|
}
|
||||||
return json.Marshal(file)
|
return json.Marshal(file)
|
||||||
@ -223,76 +220,78 @@ func (self *Chequebook) MarshalJSON() ([]byte, error) {
|
|||||||
|
|
||||||
// Save persists the chequebook on disk, remembering balance, contract address and
|
// Save persists the chequebook on disk, remembering balance, contract address and
|
||||||
// cumulative amount of funds sent for each beneficiary.
|
// cumulative amount of funds sent for each beneficiary.
|
||||||
func (self *Chequebook) Save() (err error) {
|
func (cb *Chequebook) Save() error {
|
||||||
data, err := json.MarshalIndent(self, "", " ")
|
data, err := json.MarshalIndent(cb, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.log.Trace("Saving chequebook to disk", self.path)
|
cb.log.Trace("Saving chequebook to disk", cb.path)
|
||||||
|
|
||||||
return ioutil.WriteFile(self.path, data, os.ModePerm)
|
return ioutil.WriteFile(cb.path, data, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop quits the autodeposit go routine to terminate
|
// Stop quits the autodeposit go routine to terminate
|
||||||
func (self *Chequebook) Stop() {
|
func (cb *Chequebook) Stop() {
|
||||||
defer self.lock.Unlock()
|
defer cb.lock.Unlock()
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
if self.quit != nil {
|
if cb.quit != nil {
|
||||||
close(self.quit)
|
close(cb.quit)
|
||||||
self.quit = nil
|
cb.quit = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue creates a cheque signed by the chequebook owner's private key. The
|
// Issue creates a cheque signed by the chequebook owner's private key. The
|
||||||
// signer commits to a contract (one that they own), a beneficiary and amount.
|
// signer commits to a contract (one that they own), a beneficiary and amount.
|
||||||
func (self *Chequebook) Issue(beneficiary common.Address, amount *big.Int) (ch *Cheque, err error) {
|
func (cb *Chequebook) Issue(beneficiary common.Address, amount *big.Int) (*Cheque, error) {
|
||||||
defer self.lock.Unlock()
|
defer cb.lock.Unlock()
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
|
|
||||||
if amount.Sign() <= 0 {
|
if amount.Sign() <= 0 {
|
||||||
return nil, fmt.Errorf("amount must be greater than zero (%v)", amount)
|
return nil, fmt.Errorf("amount must be greater than zero (%v)", amount)
|
||||||
}
|
}
|
||||||
if self.balance.Cmp(amount) < 0 {
|
var (
|
||||||
err = fmt.Errorf("insufficient funds to issue cheque for amount: %v. balance: %v", amount, self.balance)
|
ch *Cheque
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if cb.balance.Cmp(amount) < 0 {
|
||||||
|
err = fmt.Errorf("insufficient funds to issue cheque for amount: %v. balance: %v", amount, cb.balance)
|
||||||
} else {
|
} else {
|
||||||
var sig []byte
|
var sig []byte
|
||||||
sent, found := self.sent[beneficiary]
|
sent, found := cb.sent[beneficiary]
|
||||||
if !found {
|
if !found {
|
||||||
sent = new(big.Int)
|
sent = new(big.Int)
|
||||||
self.sent[beneficiary] = sent
|
cb.sent[beneficiary] = sent
|
||||||
}
|
}
|
||||||
sum := new(big.Int).Set(sent)
|
sum := new(big.Int).Set(sent)
|
||||||
sum.Add(sum, amount)
|
sum.Add(sum, amount)
|
||||||
|
|
||||||
sig, err = crypto.Sign(sigHash(self.contractAddr, beneficiary, sum), self.prvKey)
|
sig, err = crypto.Sign(sigHash(cb.contractAddr, beneficiary, sum), cb.prvKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ch = &Cheque{
|
ch = &Cheque{
|
||||||
Contract: self.contractAddr,
|
Contract: cb.contractAddr,
|
||||||
Beneficiary: beneficiary,
|
Beneficiary: beneficiary,
|
||||||
Amount: sum,
|
Amount: sum,
|
||||||
Sig: sig,
|
Sig: sig,
|
||||||
}
|
}
|
||||||
sent.Set(sum)
|
sent.Set(sum)
|
||||||
self.balance.Sub(self.balance, amount) // subtract amount from balance
|
cb.balance.Sub(cb.balance, amount) // subtract amount from balance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto deposit if threshold is set and balance is less then threshold
|
// auto deposit if threshold is set and balance is less then threshold
|
||||||
// note this is called even if issuing cheque fails
|
// note this is called even if issuing cheque fails
|
||||||
// so we reattempt depositing
|
// so we reattempt depositing
|
||||||
if self.threshold != nil {
|
if cb.threshold != nil {
|
||||||
if self.balance.Cmp(self.threshold) < 0 {
|
if cb.balance.Cmp(cb.threshold) < 0 {
|
||||||
send := new(big.Int).Sub(self.buffer, self.balance)
|
send := new(big.Int).Sub(cb.buffer, cb.balance)
|
||||||
self.deposit(send)
|
cb.deposit(send)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ch, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cash is a convenience method to cash any cheque.
|
// Cash is a convenience method to cash any cheque.
|
||||||
func (self *Chequebook) Cash(ch *Cheque) (txhash string, err error) {
|
func (cb *Chequebook) Cash(ch *Cheque) (string, error) {
|
||||||
return ch.Cash(self.session)
|
return ch.Cash(cb.session)
|
||||||
}
|
}
|
||||||
|
|
||||||
// data to sign: contract address, beneficiary, cumulative amount of funds ever sent
|
// data to sign: contract address, beneficiary, cumulative amount of funds ever sent
|
||||||
@ -309,73 +308,73 @@ func sigHash(contract, beneficiary common.Address, sum *big.Int) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Balance returns the current balance of the chequebook.
|
// Balance returns the current balance of the chequebook.
|
||||||
func (self *Chequebook) Balance() *big.Int {
|
func (cb *Chequebook) Balance() *big.Int {
|
||||||
defer self.lock.Unlock()
|
defer cb.lock.Unlock()
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
return new(big.Int).Set(self.balance)
|
return new(big.Int).Set(cb.balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Owner returns the owner account of the chequebook.
|
// Owner returns the owner account of the chequebook.
|
||||||
func (self *Chequebook) Owner() common.Address {
|
func (cb *Chequebook) Owner() common.Address {
|
||||||
return self.owner
|
return cb.owner
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns the on-chain contract address of the chequebook.
|
// Address returns the on-chain contract address of the chequebook.
|
||||||
func (self *Chequebook) Address() common.Address {
|
func (cb *Chequebook) Address() common.Address {
|
||||||
return self.contractAddr
|
return cb.contractAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deposit deposits money to the chequebook account.
|
// Deposit deposits money to the chequebook account.
|
||||||
func (self *Chequebook) Deposit(amount *big.Int) (string, error) {
|
func (cb *Chequebook) Deposit(amount *big.Int) (string, error) {
|
||||||
defer self.lock.Unlock()
|
defer cb.lock.Unlock()
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
return self.deposit(amount)
|
return cb.deposit(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deposit deposits amount to the chequebook account.
|
// deposit deposits amount to the chequebook account.
|
||||||
// The caller must hold self.lock.
|
// The caller must hold lock.
|
||||||
func (self *Chequebook) deposit(amount *big.Int) (string, error) {
|
func (cb *Chequebook) deposit(amount *big.Int) (string, error) {
|
||||||
// since the amount is variable here, we do not use sessions
|
// since the amount is variable here, we do not use sessions
|
||||||
depositTransactor := bind.NewKeyedTransactor(self.prvKey)
|
depositTransactor := bind.NewKeyedTransactor(cb.prvKey)
|
||||||
depositTransactor.Value = amount
|
depositTransactor.Value = amount
|
||||||
chbookRaw := &contract.ChequebookRaw{Contract: self.contract}
|
chbookRaw := &contract.ChequebookRaw{Contract: cb.contract}
|
||||||
tx, err := chbookRaw.Transfer(depositTransactor)
|
tx, err := chbookRaw.Transfer(depositTransactor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.log.Warn("Failed to fund chequebook", "amount", amount, "balance", self.balance, "target", self.buffer, "err", err)
|
cb.log.Warn("Failed to fund chequebook", "amount", amount, "balance", cb.balance, "target", cb.buffer, "err", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// assume that transaction is actually successful, we add the amount to balance right away
|
// assume that transaction is actually successful, we add the amount to balance right away
|
||||||
self.balance.Add(self.balance, amount)
|
cb.balance.Add(cb.balance, amount)
|
||||||
self.log.Trace("Deposited funds to chequebook", "amount", amount, "balance", self.balance, "target", self.buffer)
|
cb.log.Trace("Deposited funds to chequebook", "amount", amount, "balance", cb.balance, "target", cb.buffer)
|
||||||
return tx.Hash().Hex(), nil
|
return tx.Hash().Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoDeposit (re)sets interval time and amount which triggers sending funds to the
|
// AutoDeposit (re)sets interval time and amount which triggers sending funds to the
|
||||||
// chequebook. Contract backend needs to be set if threshold is not less than buffer, then
|
// chequebook. Contract backend needs to be set if threshold is not less than buffer, then
|
||||||
// deposit will be triggered on every new cheque issued.
|
// deposit will be triggered on every new cheque issued.
|
||||||
func (self *Chequebook) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
|
func (cb *Chequebook) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
|
||||||
defer self.lock.Unlock()
|
defer cb.lock.Unlock()
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
self.threshold = threshold
|
cb.threshold = threshold
|
||||||
self.buffer = buffer
|
cb.buffer = buffer
|
||||||
self.autoDeposit(interval)
|
cb.autoDeposit(interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
// autoDeposit starts a goroutine that periodically sends funds to the chequebook
|
// autoDeposit starts a goroutine that periodically sends funds to the chequebook
|
||||||
// contract caller holds the lock the go routine terminates if Chequebook.quit is closed.
|
// contract caller holds the lock the go routine terminates if Chequebook.quit is closed.
|
||||||
func (self *Chequebook) autoDeposit(interval time.Duration) {
|
func (cb *Chequebook) autoDeposit(interval time.Duration) {
|
||||||
if self.quit != nil {
|
if cb.quit != nil {
|
||||||
close(self.quit)
|
close(cb.quit)
|
||||||
self.quit = nil
|
cb.quit = nil
|
||||||
}
|
}
|
||||||
// if threshold >= balance autodeposit after every cheque issued
|
// if threshold >= balance autodeposit after every cheque issued
|
||||||
if interval == time.Duration(0) || self.threshold != nil && self.buffer != nil && self.threshold.Cmp(self.buffer) >= 0 {
|
if interval == time.Duration(0) || cb.threshold != nil && cb.buffer != nil && cb.threshold.Cmp(cb.buffer) >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
self.quit = make(chan bool)
|
cb.quit = make(chan bool)
|
||||||
quit := self.quit
|
quit := cb.quit
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -383,15 +382,15 @@ func (self *Chequebook) autoDeposit(interval time.Duration) {
|
|||||||
case <-quit:
|
case <-quit:
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
self.lock.Lock()
|
cb.lock.Lock()
|
||||||
if self.balance.Cmp(self.buffer) < 0 {
|
if cb.balance.Cmp(cb.buffer) < 0 {
|
||||||
amount := new(big.Int).Sub(self.buffer, self.balance)
|
amount := new(big.Int).Sub(cb.buffer, cb.balance)
|
||||||
txhash, err := self.deposit(amount)
|
txhash, err := cb.deposit(amount)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
self.txhash = txhash
|
cb.txhash = txhash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lock.Unlock()
|
cb.lock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -404,26 +403,26 @@ type Outbox struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOutbox creates an outbox.
|
// NewOutbox creates an outbox.
|
||||||
func NewOutbox(chbook *Chequebook, beneficiary common.Address) *Outbox {
|
func NewOutbox(cb *Chequebook, beneficiary common.Address) *Outbox {
|
||||||
return &Outbox{chbook, beneficiary}
|
return &Outbox{cb, beneficiary}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue creates cheque.
|
// Issue creates cheque.
|
||||||
func (self *Outbox) Issue(amount *big.Int) (swap.Promise, error) {
|
func (o *Outbox) Issue(amount *big.Int) (swap.Promise, error) {
|
||||||
return self.chequeBook.Issue(self.beneficiary, amount)
|
return o.chequeBook.Issue(o.beneficiary, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoDeposit enables auto-deposits on the underlying chequebook.
|
// AutoDeposit enables auto-deposits on the underlying chequebook.
|
||||||
func (self *Outbox) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
|
func (o *Outbox) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
|
||||||
self.chequeBook.AutoDeposit(interval, threshold, buffer)
|
o.chequeBook.AutoDeposit(interval, threshold, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop helps satisfy the swap.OutPayment interface.
|
// Stop helps satisfy the swap.OutPayment interface.
|
||||||
func (self *Outbox) Stop() {}
|
func (o *Outbox) Stop() {}
|
||||||
|
|
||||||
// String implements fmt.Stringer.
|
// String implements fmt.Stringer.
|
||||||
func (self *Outbox) String() string {
|
func (o *Outbox) String() string {
|
||||||
return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", self.chequeBook.Address().Hex(), self.beneficiary.Hex(), self.chequeBook.Balance())
|
return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", o.chequeBook.Address().Hex(), o.beneficiary.Hex(), o.chequeBook.Balance())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inbox can deposit, verify and cash cheques from a single contract to a single
|
// Inbox can deposit, verify and cash cheques from a single contract to a single
|
||||||
@ -445,7 +444,7 @@ type Inbox struct {
|
|||||||
|
|
||||||
// NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated
|
// NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated
|
||||||
// from blockchain when first cheque is received.
|
// from blockchain when first cheque is received.
|
||||||
func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address, signer *ecdsa.PublicKey, abigen bind.ContractBackend) (self *Inbox, err error) {
|
func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address, signer *ecdsa.PublicKey, abigen bind.ContractBackend) (*Inbox, error) {
|
||||||
if signer == nil {
|
if signer == nil {
|
||||||
return nil, fmt.Errorf("signer is null")
|
return nil, fmt.Errorf("signer is null")
|
||||||
}
|
}
|
||||||
@ -461,7 +460,7 @@ func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address
|
|||||||
}
|
}
|
||||||
sender := transactOpts.From
|
sender := transactOpts.From
|
||||||
|
|
||||||
self = &Inbox{
|
inbox := &Inbox{
|
||||||
contract: contractAddr,
|
contract: contractAddr,
|
||||||
beneficiary: beneficiary,
|
beneficiary: beneficiary,
|
||||||
sender: sender,
|
sender: sender,
|
||||||
@ -470,59 +469,61 @@ func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address
|
|||||||
cashed: new(big.Int).Set(common.Big0),
|
cashed: new(big.Int).Set(common.Big0),
|
||||||
log: log.New("contract", contractAddr),
|
log: log.New("contract", contractAddr),
|
||||||
}
|
}
|
||||||
self.log.Trace("New chequebook inbox initialized", "beneficiary", self.beneficiary, "signer", hexutil.Bytes(crypto.FromECDSAPub(signer)))
|
inbox.log.Trace("New chequebook inbox initialized", "beneficiary", inbox.beneficiary, "signer", hexutil.Bytes(crypto.FromECDSAPub(signer)))
|
||||||
return
|
return inbox, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Inbox) String() string {
|
func (i *Inbox) String() string {
|
||||||
return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", self.contract.Hex(), self.beneficiary.Hex(), self.cheque.Amount)
|
return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", i.contract.Hex(), i.beneficiary.Hex(), i.cheque.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop quits the autocash goroutine.
|
// Stop quits the autocash goroutine.
|
||||||
func (self *Inbox) Stop() {
|
func (i *Inbox) Stop() {
|
||||||
defer self.lock.Unlock()
|
defer i.lock.Unlock()
|
||||||
self.lock.Lock()
|
i.lock.Lock()
|
||||||
if self.quit != nil {
|
if i.quit != nil {
|
||||||
close(self.quit)
|
close(i.quit)
|
||||||
self.quit = nil
|
i.quit = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cash attempts to cash the current cheque.
|
// Cash attempts to cash the current cheque.
|
||||||
func (self *Inbox) Cash() (txhash string, err error) {
|
func (i *Inbox) Cash() (string, error) {
|
||||||
if self.cheque != nil {
|
if i.cheque == nil {
|
||||||
txhash, err = self.cheque.Cash(self.session)
|
return "", nil
|
||||||
self.log.Trace("Cashing in chequebook cheque", "amount", self.cheque.Amount, "beneficiary", self.beneficiary)
|
|
||||||
self.cashed = self.cheque.Amount
|
|
||||||
}
|
}
|
||||||
return
|
txhash, err := i.cheque.Cash(i.session)
|
||||||
|
i.log.Trace("Cashing in chequebook cheque", "amount", i.cheque.Amount, "beneficiary", i.beneficiary)
|
||||||
|
i.cashed = i.cheque.Amount
|
||||||
|
|
||||||
|
return txhash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoCash (re)sets maximum time and amount which triggers cashing of the last uncashed
|
// AutoCash (re)sets maximum time and amount which triggers cashing of the last uncashed
|
||||||
// cheque if maxUncashed is set to 0, then autocash on receipt.
|
// cheque if maxUncashed is set to 0, then autocash on receipt.
|
||||||
func (self *Inbox) AutoCash(cashInterval time.Duration, maxUncashed *big.Int) {
|
func (i *Inbox) AutoCash(cashInterval time.Duration, maxUncashed *big.Int) {
|
||||||
defer self.lock.Unlock()
|
defer i.lock.Unlock()
|
||||||
self.lock.Lock()
|
i.lock.Lock()
|
||||||
self.maxUncashed = maxUncashed
|
i.maxUncashed = maxUncashed
|
||||||
self.autoCash(cashInterval)
|
i.autoCash(cashInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
// autoCash starts a loop that periodically clears the last cheque
|
// autoCash starts a loop that periodically clears the last cheque
|
||||||
// if the peer is trusted. Clearing period could be 24h or a week.
|
// if the peer is trusted. Clearing period could be 24h or a week.
|
||||||
// The caller must hold self.lock.
|
// The caller must hold lock.
|
||||||
func (self *Inbox) autoCash(cashInterval time.Duration) {
|
func (i *Inbox) autoCash(cashInterval time.Duration) {
|
||||||
if self.quit != nil {
|
if i.quit != nil {
|
||||||
close(self.quit)
|
close(i.quit)
|
||||||
self.quit = nil
|
i.quit = nil
|
||||||
}
|
}
|
||||||
// if maxUncashed is set to 0, then autocash on receipt
|
// if maxUncashed is set to 0, then autocash on receipt
|
||||||
if cashInterval == time.Duration(0) || self.maxUncashed != nil && self.maxUncashed.Sign() == 0 {
|
if cashInterval == time.Duration(0) || i.maxUncashed != nil && i.maxUncashed.Sign() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(cashInterval)
|
ticker := time.NewTicker(cashInterval)
|
||||||
self.quit = make(chan bool)
|
i.quit = make(chan bool)
|
||||||
quit := self.quit
|
quit := i.quit
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -530,14 +531,14 @@ func (self *Inbox) autoCash(cashInterval time.Duration) {
|
|||||||
case <-quit:
|
case <-quit:
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
self.lock.Lock()
|
i.lock.Lock()
|
||||||
if self.cheque != nil && self.cheque.Amount.Cmp(self.cashed) != 0 {
|
if i.cheque != nil && i.cheque.Amount.Cmp(i.cashed) != 0 {
|
||||||
txhash, err := self.Cash()
|
txhash, err := i.Cash()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
self.txhash = txhash
|
i.txhash = txhash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lock.Unlock()
|
i.lock.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -545,56 +546,56 @@ func (self *Inbox) autoCash(cashInterval time.Duration) {
|
|||||||
|
|
||||||
// Receive is called to deposit the latest cheque to the incoming Inbox.
|
// Receive is called to deposit the latest cheque to the incoming Inbox.
|
||||||
// The given promise must be a *Cheque.
|
// The given promise must be a *Cheque.
|
||||||
func (self *Inbox) Receive(promise swap.Promise) (*big.Int, error) {
|
func (i *Inbox) Receive(promise swap.Promise) (*big.Int, error) {
|
||||||
ch := promise.(*Cheque)
|
ch := promise.(*Cheque)
|
||||||
|
|
||||||
defer self.lock.Unlock()
|
defer i.lock.Unlock()
|
||||||
self.lock.Lock()
|
i.lock.Lock()
|
||||||
|
|
||||||
var sum *big.Int
|
var sum *big.Int
|
||||||
if self.cheque == nil {
|
if i.cheque == nil {
|
||||||
// the sum is checked against the blockchain once a cheque is received
|
// the sum is checked against the blockchain once a cheque is received
|
||||||
tally, err := self.session.Sent(self.beneficiary)
|
tally, err := i.session.Sent(i.beneficiary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("inbox: error calling backend to set amount: %v", err)
|
return nil, fmt.Errorf("inbox: error calling backend to set amount: %v", err)
|
||||||
}
|
}
|
||||||
sum = tally
|
sum = tally
|
||||||
} else {
|
} else {
|
||||||
sum = self.cheque.Amount
|
sum = i.cheque.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
amount, err := ch.Verify(self.signer, self.contract, self.beneficiary, sum)
|
amount, err := ch.Verify(i.signer, i.contract, i.beneficiary, sum)
|
||||||
var uncashed *big.Int
|
var uncashed *big.Int
|
||||||
if err == nil {
|
if err == nil {
|
||||||
self.cheque = ch
|
i.cheque = ch
|
||||||
|
|
||||||
if self.maxUncashed != nil {
|
if i.maxUncashed != nil {
|
||||||
uncashed = new(big.Int).Sub(ch.Amount, self.cashed)
|
uncashed = new(big.Int).Sub(ch.Amount, i.cashed)
|
||||||
if self.maxUncashed.Cmp(uncashed) < 0 {
|
if i.maxUncashed.Cmp(uncashed) < 0 {
|
||||||
self.Cash()
|
i.Cash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.log.Trace("Received cheque in chequebook inbox", "amount", amount, "uncashed", uncashed)
|
i.log.Trace("Received cheque in chequebook inbox", "amount", amount, "uncashed", uncashed)
|
||||||
}
|
}
|
||||||
|
|
||||||
return amount, err
|
return amount, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify verifies cheque for signer, contract, beneficiary, amount, valid signature.
|
// Verify verifies cheque for signer, contract, beneficiary, amount, valid signature.
|
||||||
func (self *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary common.Address, sum *big.Int) (*big.Int, error) {
|
func (ch *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary common.Address, sum *big.Int) (*big.Int, error) {
|
||||||
log.Trace("Verifying chequebook cheque", "cheque", self, "sum", sum)
|
log.Trace("Verifying chequebook cheque", "cheque", ch, "sum", sum)
|
||||||
if sum == nil {
|
if sum == nil {
|
||||||
return nil, fmt.Errorf("invalid amount")
|
return nil, fmt.Errorf("invalid amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.Beneficiary != beneficiary {
|
if ch.Beneficiary != beneficiary {
|
||||||
return nil, fmt.Errorf("beneficiary mismatch: %v != %v", self.Beneficiary.Hex(), beneficiary.Hex())
|
return nil, fmt.Errorf("beneficiary mismatch: %v != %v", ch.Beneficiary.Hex(), beneficiary.Hex())
|
||||||
}
|
}
|
||||||
if self.Contract != contract {
|
if ch.Contract != contract {
|
||||||
return nil, fmt.Errorf("contract mismatch: %v != %v", self.Contract.Hex(), contract.Hex())
|
return nil, fmt.Errorf("contract mismatch: %v != %v", ch.Contract.Hex(), contract.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
amount := new(big.Int).Set(self.Amount)
|
amount := new(big.Int).Set(ch.Amount)
|
||||||
if sum != nil {
|
if sum != nil {
|
||||||
amount.Sub(amount, sum)
|
amount.Sub(amount, sum)
|
||||||
if amount.Sign() <= 0 {
|
if amount.Sign() <= 0 {
|
||||||
@ -602,7 +603,7 @@ func (self *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary com
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey, err := crypto.SigToPub(sigHash(self.Contract, beneficiary, self.Amount), self.Sig)
|
pubKey, err := crypto.SigToPub(sigHash(ch.Contract, beneficiary, ch.Amount), ch.Sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid signature: %v", err)
|
return nil, fmt.Errorf("invalid signature: %v", err)
|
||||||
}
|
}
|
||||||
@ -621,9 +622,9 @@ func sig2vrs(sig []byte) (v byte, r, s [32]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cash cashes the cheque by sending an Ethereum transaction.
|
// Cash cashes the cheque by sending an Ethereum transaction.
|
||||||
func (self *Cheque) Cash(session *contract.ChequebookSession) (string, error) {
|
func (ch *Cheque) Cash(session *contract.ChequebookSession) (string, error) {
|
||||||
v, r, s := sig2vrs(self.Sig)
|
v, r, s := sig2vrs(ch.Sig)
|
||||||
tx, err := session.Cash(self.Beneficiary, self.Amount, v, r, s)
|
tx, err := session.Cash(ch.Beneficiary, ch.Amount, v, r, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -632,7 +633,7 @@ func (self *Cheque) Cash(session *contract.ChequebookSession) (string, error) {
|
|||||||
|
|
||||||
// ValidateCode checks that the on-chain code at address matches the expected chequebook
|
// ValidateCode checks that the on-chain code at address matches the expected chequebook
|
||||||
// contract code. This is used to detect suicided chequebooks.
|
// contract code. This is used to detect suicided chequebooks.
|
||||||
func ValidateCode(ctx context.Context, b Backend, address common.Address) (ok bool, err error) {
|
func ValidateCode(ctx context.Context, b Backend, address common.Address) (bool, error) {
|
||||||
code, err := b.CodeAt(ctx, address, nil)
|
code, err := b.CodeAt(ctx, address, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -205,22 +205,22 @@ func (_Chequebook *ChequebookCallerSession) Sent(arg0 common.Address) (*big.Int,
|
|||||||
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
||||||
//
|
//
|
||||||
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
||||||
func (_Chequebook *ChequebookTransactor) Cash(opts *bind.TransactOpts, beneficiary common.Address, amount *big.Int, sig_v uint8, sig_r [32]byte, sig_s [32]byte) (*types.Transaction, error) {
|
func (_Chequebook *ChequebookTransactor) Cash(opts *bind.TransactOpts, beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
|
||||||
return _Chequebook.contract.Transact(opts, "cash", beneficiary, amount, sig_v, sig_r, sig_s)
|
return _Chequebook.contract.Transact(opts, "cash", beneficiary, amount, sigV, sigR, sigS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
||||||
//
|
//
|
||||||
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
||||||
func (_Chequebook *ChequebookSession) Cash(beneficiary common.Address, amount *big.Int, sig_v uint8, sig_r [32]byte, sig_s [32]byte) (*types.Transaction, error) {
|
func (_Chequebook *ChequebookSession) Cash(beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
|
||||||
return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sig_v, sig_r, sig_s)
|
return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sigV, sigR, sigS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
|
||||||
//
|
//
|
||||||
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
|
||||||
func (_Chequebook *ChequebookTransactorSession) Cash(beneficiary common.Address, amount *big.Int, sig_v uint8, sig_r [32]byte, sig_s [32]byte) (*types.Transaction, error) {
|
func (_Chequebook *ChequebookTransactorSession) Cash(beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
|
||||||
return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sig_v, sig_r, sig_s)
|
return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sigV, sigR, sigS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
|
// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
|
||||||
|
@ -227,10 +227,10 @@ func (_ENS *ENSCallerSession) Resolver(node [32]byte) (common.Address, error) {
|
|||||||
return _ENS.Contract.Resolver(&_ENS.CallOpts, node)
|
return _ENS.Contract.Resolver(&_ENS.CallOpts, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
|
// TTL is a free data retrieval call binding the contract method 0x16a25cbd.
|
||||||
//
|
//
|
||||||
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
||||||
func (_ENS *ENSCaller) Ttl(opts *bind.CallOpts, node [32]byte) (uint64, error) {
|
func (_ENS *ENSCaller) TTL(opts *bind.CallOpts, node [32]byte) (uint64, error) {
|
||||||
var (
|
var (
|
||||||
ret0 = new(uint64)
|
ret0 = new(uint64)
|
||||||
)
|
)
|
||||||
@ -239,18 +239,18 @@ func (_ENS *ENSCaller) Ttl(opts *bind.CallOpts, node [32]byte) (uint64, error) {
|
|||||||
return *ret0, err
|
return *ret0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
|
// TTL is a free data retrieval call binding the contract method 0x16a25cbd.
|
||||||
//
|
//
|
||||||
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
||||||
func (_ENS *ENSSession) Ttl(node [32]byte) (uint64, error) {
|
func (_ENS *ENSSession) TTL(node [32]byte) (uint64, error) {
|
||||||
return _ENS.Contract.Ttl(&_ENS.CallOpts, node)
|
return _ENS.Contract.TTL(&_ENS.CallOpts, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
|
// TTL is a free data retrieval call binding the contract method 0x16a25cbd.
|
||||||
//
|
//
|
||||||
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
// Solidity: function ttl(node bytes32) constant returns(uint64)
|
||||||
func (_ENS *ENSCallerSession) Ttl(node [32]byte) (uint64, error) {
|
func (_ENS *ENSCallerSession) TTL(node [32]byte) (uint64, error) {
|
||||||
return _ENS.Contract.Ttl(&_ENS.CallOpts, node)
|
return _ENS.Contract.TTL(&_ENS.CallOpts, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
|
// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
|
||||||
@ -682,7 +682,7 @@ func (it *ENSNewTTLIterator) Close() error {
|
|||||||
// ENSNewTTL represents a NewTTL event raised by the ENS contract.
|
// ENSNewTTL represents a NewTTL event raised by the ENS contract.
|
||||||
type ENSNewTTL struct {
|
type ENSNewTTL struct {
|
||||||
Node [32]byte
|
Node [32]byte
|
||||||
Ttl uint64
|
TTL uint64
|
||||||
Raw types.Log // Blockchain specific contextual infos
|
Raw types.Log // Blockchain specific contextual infos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ var (
|
|||||||
TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010")
|
TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010")
|
||||||
)
|
)
|
||||||
|
|
||||||
// swarm domain name registry and resolver
|
// ENS is the swarm domain name registry and resolver
|
||||||
type ENS struct {
|
type ENS struct {
|
||||||
*contract.ENSSession
|
*contract.ENSSession
|
||||||
contractBackend bind.ContractBackend
|
contractBackend bind.ContractBackend
|
||||||
@ -48,7 +48,6 @@ func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contra
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ENS{
|
return &ENS{
|
||||||
&contract.ENSSession{
|
&contract.ENSSession{
|
||||||
Contract: ens,
|
Contract: ens,
|
||||||
@ -60,27 +59,24 @@ func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contra
|
|||||||
|
|
||||||
// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar.
|
// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar.
|
||||||
func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) {
|
func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) {
|
||||||
// Deploy the ENS registry.
|
// Deploy the ENS registry
|
||||||
ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend)
|
ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ensAddr, nil, err
|
return ensAddr, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ens, err := NewENS(transactOpts, ensAddr, contractBackend)
|
ens, err := NewENS(transactOpts, ensAddr, contractBackend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ensAddr, nil, err
|
return ensAddr, nil, err
|
||||||
}
|
}
|
||||||
|
// Deploy the registrar
|
||||||
// Deploy the registrar.
|
|
||||||
regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
|
regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ensAddr, nil, err
|
return ensAddr, nil, err
|
||||||
}
|
}
|
||||||
// Set the registrar as owner of the ENS root.
|
// Set the registrar as owner of the ENS root
|
||||||
if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil {
|
if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil {
|
||||||
return ensAddr, nil, err
|
return ensAddr, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ensAddr, ens, nil
|
return ensAddr, ens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,122 +85,111 @@ func ensParentNode(name string) (common.Hash, common.Hash) {
|
|||||||
label := crypto.Keccak256Hash([]byte(parts[0]))
|
label := crypto.Keccak256Hash([]byte(parts[0]))
|
||||||
if len(parts) == 1 {
|
if len(parts) == 1 {
|
||||||
return [32]byte{}, label
|
return [32]byte{}, label
|
||||||
} else {
|
}
|
||||||
parentNode, parentLabel := ensParentNode(parts[1])
|
parentNode, parentLabel := ensParentNode(parts[1])
|
||||||
return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label
|
return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func EnsNode(name string) common.Hash {
|
func EnsNode(name string) common.Hash {
|
||||||
parentNode, parentLabel := ensParentNode(name)
|
parentNode, parentLabel := ensParentNode(name)
|
||||||
return crypto.Keccak256Hash(parentNode[:], parentLabel[:])
|
return crypto.Keccak256Hash(parentNode[:], parentLabel[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) {
|
func (ens *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) {
|
||||||
resolverAddr, err := self.Resolver(node)
|
resolverAddr, err := ens.Resolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
resolver, err := contract.NewPublicResolver(resolverAddr, ens.contractBackend)
|
||||||
resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &contract.PublicResolverSession{
|
return &contract.PublicResolverSession{
|
||||||
Contract: resolver,
|
Contract: resolver,
|
||||||
TransactOpts: self.TransactOpts,
|
TransactOpts: ens.TransactOpts,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) {
|
func (ens *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) {
|
||||||
registrarAddr, err := self.Owner(node)
|
registrarAddr, err := ens.Owner(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
registrar, err := contract.NewFIFSRegistrar(registrarAddr, ens.contractBackend)
|
||||||
registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &contract.FIFSRegistrarSession{
|
return &contract.FIFSRegistrarSession{
|
||||||
Contract: registrar,
|
Contract: registrar,
|
||||||
TransactOpts: self.TransactOpts,
|
TransactOpts: ens.TransactOpts,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve is a non-transactional call that returns the content hash associated with a name.
|
// Resolve is a non-transactional call that returns the content hash associated with a name.
|
||||||
func (self *ENS) Resolve(name string) (common.Hash, error) {
|
func (ens *ENS) Resolve(name string) (common.Hash, error) {
|
||||||
node := EnsNode(name)
|
node := EnsNode(name)
|
||||||
|
|
||||||
resolver, err := self.getResolver(node)
|
resolver, err := ens.getResolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := resolver.Content(node)
|
ret, err := resolver.Content(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return common.BytesToHash(ret[:]), nil
|
return common.BytesToHash(ret[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addr is a non-transactional call that returns the address associated with a name.
|
// Addr is a non-transactional call that returns the address associated with a name.
|
||||||
func (self *ENS) Addr(name string) (common.Address, error) {
|
func (ens *ENS) Addr(name string) (common.Address, error) {
|
||||||
node := EnsNode(name)
|
node := EnsNode(name)
|
||||||
|
|
||||||
resolver, err := self.getResolver(node)
|
resolver, err := ens.getResolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := resolver.Addr(node)
|
ret, err := resolver.Addr(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return common.BytesToAddress(ret[:]), nil
|
return common.BytesToAddress(ret[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress sets the address associated with a name. Only works if the caller
|
// SetAddress sets the address associated with a name. Only works if the caller
|
||||||
// owns the name, and the associated resolver implements a `setAddress` function.
|
// owns the name, and the associated resolver implements a `setAddress` function.
|
||||||
func (self *ENS) SetAddr(name string, addr common.Address) (*types.Transaction, error) {
|
func (ens *ENS) SetAddr(name string, addr common.Address) (*types.Transaction, error) {
|
||||||
node := EnsNode(name)
|
node := EnsNode(name)
|
||||||
|
|
||||||
resolver, err := self.getResolver(node)
|
resolver, err := ens.getResolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
opts := ens.TransactOpts
|
||||||
opts := self.TransactOpts
|
|
||||||
opts.GasLimit = 200000
|
opts.GasLimit = 200000
|
||||||
return resolver.Contract.SetAddr(&opts, node, addr)
|
return resolver.Contract.SetAddr(&opts, node, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register registers a new domain name for the caller, making them the owner of the new name.
|
// 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.
|
// Only works if the registrar for the parent domain implements the FIFS registrar protocol.
|
||||||
func (self *ENS) Register(name string) (*types.Transaction, error) {
|
func (ens *ENS) Register(name string) (*types.Transaction, error) {
|
||||||
parentNode, label := ensParentNode(name)
|
parentNode, label := ensParentNode(name)
|
||||||
registrar, err := self.getRegistrar(parentNode)
|
registrar, err := ens.getRegistrar(parentNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return registrar.Contract.Register(&self.TransactOpts, label, self.TransactOpts.From)
|
return registrar.Contract.Register(&ens.TransactOpts, label, ens.TransactOpts.From)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContentHash sets the content hash associated with a name. Only works if the caller
|
// 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.
|
// owns the name, and the associated resolver implements a `setContent` function.
|
||||||
func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
|
func (ens *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
|
||||||
node := EnsNode(name)
|
node := EnsNode(name)
|
||||||
|
|
||||||
resolver, err := self.getResolver(node)
|
resolver, err := ens.getResolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
opts := ens.TransactOpts
|
||||||
opts := self.TransactOpts
|
|
||||||
opts.GasLimit = 200000
|
opts.GasLimit = 200000
|
||||||
return resolver.Contract.SetContent(&opts, node, hash)
|
return resolver.Contract.SetContent(&opts, node, hash)
|
||||||
}
|
}
|
||||||
|
@ -491,7 +491,7 @@ func (self *Swarm) APIs() []rpc.API {
|
|||||||
{
|
{
|
||||||
Namespace: "chequebook",
|
Namespace: "chequebook",
|
||||||
Version: chequebook.Version,
|
Version: chequebook.Version,
|
||||||
Service: chequebook.NewApi(self.config.Swap.Chequebook),
|
Service: chequebook.NewAPI(self.config.Swap.Chequebook),
|
||||||
Public: false,
|
Public: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user