Kaynağa Gözat

contracts/chequebook: add chequebook contract wrapper

The wrapper code is adapted from the swarm/services/chequebook package
with the following mostly cosmetic changes:

* The code now uses the new Go API interfaces to query balances. Some
  minor functional changes were required to make this work.
* The package no longer depends on swarm/services/swap/swap. References
  to swap.Promise are replaced by interface{}, the base type of Promise.
  This is temporary.
* The contract wrapper has been regenerated with latest abigen
  and solc v0.3.6.
* There is a new generator that creates the 'deployed code' variable.
* Documentation comments now follow the recommended godoc style.
* [CHEQUEBOOK] log prefixes are gone.
* LGPL license headers have been added to all files.
Viktor Trón 9 yıl önce
ebeveyn
işleme
6c8b023298

+ 68 - 0
contracts/chequebook/api.go

@@ -0,0 +1,68 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package chequebook
+
+import (
+	"errors"
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/common"
+)
+
+const Version = "1.0"
+
+var errNoChequebook = errors.New("no chequebook")
+
+type Api struct {
+	chequebookf func() *Chequebook
+}
+
+func NewApi(ch func() *Chequebook) *Api {
+	return &Api{ch}
+}
+
+func (self *Api) Balance() (string, error) {
+	ch := self.chequebookf()
+	if ch == nil {
+		return "", errNoChequebook
+	}
+	return ch.Balance().String(), nil
+}
+
+func (self *Api) Issue(beneficiary common.Address, amount *big.Int) (cheque *Cheque, err error) {
+	ch := self.chequebookf()
+	if ch == nil {
+		return nil, errNoChequebook
+	}
+	return ch.Issue(beneficiary, amount)
+}
+
+func (self *Api) Cash(cheque *Cheque) (txhash string, err error) {
+	ch := self.chequebookf()
+	if ch == nil {
+		return "", errNoChequebook
+	}
+	return ch.Cash(cheque)
+}
+
+func (self *Api) Deposit(amount *big.Int) (txhash string, err error) {
+	ch := self.chequebookf()
+	if ch == nil {
+		return "", errNoChequebook
+	}
+	return ch.Deposit(amount)
+}

+ 643 - 0
contracts/chequebook/cheque.go

@@ -0,0 +1,643 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// Package chequebook package wraps the 'chequebook' Ethereum smart contract.
+//
+// The functions in this package allow using chequebook for
+// issuing, receiving, verifying cheques in ether; (auto)cashing cheques in ether
+// as well as (auto)depositing ether to the chequebook contract.
+package chequebook
+
+//go:generate abigen --sol contract/chequebook.sol --pkg contract --out contract/chequebook.go
+//go:generate go run ./gencode.go
+
+import (
+	"bytes"
+	"crypto/ecdsa"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"math/big"
+	"os"
+	"sync"
+	"time"
+
+	"github.com/ethereum/go-ethereum/accounts/abi/bind"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/contracts/chequebook/contract"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
+	"golang.org/x/net/context"
+)
+
+// TODO(zelig): watch peer solvency and notify of bouncing cheques
+// TODO(zelig): enable paying with cheque by signing off
+
+// Some functionality require interacting with the blockchain:
+// * setting current balance on peer's chequebook
+// * sending the transaction to cash the cheque
+// * depositing ether to the chequebook
+// * watching incoming ether
+
+var (
+	gasToCash = big.NewInt(2000000) // gas cost of a cash transaction using chequebook
+	// gasToDeploy = big.NewInt(3000000)
+)
+
+// Backend wraps all methods required for chequebook operation.
+type Backend interface {
+	bind.ContractBackend
+	TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
+	BalanceAt(ctx context.Context, address common.Address, blockNum *big.Int) (*big.Int, error)
+}
+
+// Cheque represents a payment promise to a single beneficiary.
+type Cheque struct {
+	Contract    common.Address // address of chequebook, needed to avoid cross-contract submission
+	Beneficiary common.Address
+	Amount      *big.Int // cumulative amount of all funds sent
+	Sig         []byte   // signature Sign(Keccak256(contract, beneficiary, amount), prvKey)
+}
+
+func (self *Cheque) String() string {
+	return fmt.Sprintf("contract: %s, beneficiary: %s, amount: %v, signature: %x", self.Contract.Hex(), self.Beneficiary.Hex(), self.Amount, self.Sig)
+}
+
+type Params struct {
+	ContractCode, ContractAbi string
+}
+
+var ContractParams = &Params{contract.ChequebookBin, contract.ChequebookABI}
+
+// Chequebook can create and sign cheques from a single contract to multiple beneficiaries.
+// It is the outgoing payment handler for peer to peer micropayments.
+type Chequebook struct {
+	path     string                      // path to chequebook file
+	prvKey   *ecdsa.PrivateKey           // private key to sign cheque with
+	lock     sync.Mutex                  //
+	backend  Backend                     // blockchain API
+	quit     chan bool                   // when closed causes autodeposit to stop
+	owner    common.Address              // owner address (derived from pubkey)
+	contract *contract.Chequebook        // abigen binding
+	session  *contract.ChequebookSession // abigen binding with Tx Opts
+
+	// persisted fields
+	balance      *big.Int                    // not synced with blockchain
+	contractAddr common.Address              // contract address
+	sent         map[common.Address]*big.Int //tallies for beneficiarys
+
+	txhash    string   // tx hash of last deposit tx
+	threshold *big.Int // threshold that triggers autodeposit if not nil
+	buffer    *big.Int // buffer to keep on top of balance for fork protection
+}
+
+func (self *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)
+}
+
+// NewChequebook creates a new Chequebook.
+func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.PrivateKey, backend Backend) (self *Chequebook, err error) {
+	balance := new(big.Int)
+	sent := make(map[common.Address]*big.Int)
+
+	chbook, err := contract.NewChequebook(contractAddr, backend)
+	if err != nil {
+		return nil, err
+	}
+	transactOpts := bind.NewKeyedTransactor(prvKey)
+	session := &contract.ChequebookSession{
+		Contract:     chbook,
+		TransactOpts: *transactOpts,
+	}
+
+	self = &Chequebook{
+		prvKey:       prvKey,
+		balance:      balance,
+		contractAddr: contractAddr,
+		sent:         sent,
+		path:         path,
+		backend:      backend,
+		owner:        transactOpts.From,
+		contract:     chbook,
+		session:      session,
+	}
+
+	if (contractAddr != common.Address{}) {
+		self.setBalanceFromBlockChain()
+		glog.V(logger.Detail).Infof("new chequebook initialised from %s (owner: %v, balance: %s)", contractAddr.Hex(), self.owner.Hex(), self.balance.String())
+	}
+	return
+}
+
+func (self *Chequebook) setBalanceFromBlockChain() {
+	balance, err := self.backend.BalanceAt(context.TODO(), self.contractAddr, nil)
+	if err != nil {
+		glog.V(logger.Error).Infof("can't get balance: %v", err)
+	} else {
+		self.balance.Set(balance)
+	}
+}
+
+// LoadChequebook loads a chequebook from disk (file path).
+func LoadChequebook(path string, prvKey *ecdsa.PrivateKey, backend Backend, checkBalance bool) (self *Chequebook, err error) {
+	var data []byte
+	data, err = ioutil.ReadFile(path)
+	if err != nil {
+		return
+	}
+
+	self, _ = NewChequebook(path, common.Address{}, prvKey, backend)
+
+	err = json.Unmarshal(data, self)
+	if err != nil {
+		return nil, err
+	}
+	if checkBalance {
+		self.setBalanceFromBlockChain()
+	}
+
+	glog.V(logger.Detail).Infof("loaded chequebook (%s, owner: %v, balance: %v) initialised from %v", self.contractAddr.Hex(), self.owner.Hex(), self.balance, path)
+
+	return
+}
+
+// chequebookFile is the JSON representation of a chequebook.
+type chequebookFile struct {
+	Balance  string
+	Contract string
+	Owner    string
+	Sent     map[string]string
+}
+
+// UnmarshalJSON deserialises a chequebook.
+func (self *Chequebook) UnmarshalJSON(data []byte) error {
+	var file chequebookFile
+	err := json.Unmarshal(data, &file)
+	if err != nil {
+		return err
+	}
+	_, ok := self.balance.SetString(file.Balance, 10)
+	if !ok {
+		return fmt.Errorf("cumulative amount sent: unable to convert string to big integer: %v", file.Balance)
+	}
+	self.contractAddr = common.HexToAddress(file.Contract)
+	for addr, sent := range file.Sent {
+		self.sent[common.HexToAddress(addr)], ok = new(big.Int).SetString(sent, 10)
+		if !ok {
+			return fmt.Errorf("beneficiary %v cumulative amount sent: unable to convert string to big integer: %v", addr, sent)
+		}
+	}
+	return nil
+}
+
+// MarshalJSON serialises a chequebook.
+func (self *Chequebook) MarshalJSON() ([]byte, error) {
+	var file = &chequebookFile{
+		Balance:  self.balance.String(),
+		Contract: self.contractAddr.Hex(),
+		Owner:    self.owner.Hex(),
+		Sent:     make(map[string]string),
+	}
+	for addr, sent := range self.sent {
+		file.Sent[addr.Hex()] = sent.String()
+	}
+	return json.Marshal(file)
+}
+
+// Save persists the chequebook on disk, remembering balance, contract address and
+// cumulative amount of funds sent for each beneficiary.
+func (self *Chequebook) Save() (err error) {
+	data, err := json.MarshalIndent(self, "", " ")
+	if err != nil {
+		return err
+	}
+	glog.V(logger.Detail).Infof("saving chequebook (%s) to %v", self.contractAddr.Hex(), self.path)
+
+	return ioutil.WriteFile(self.path, data, os.ModePerm)
+}
+
+// Stop quits the autodeposit go routine to terminate
+func (self *Chequebook) Stop() {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	if self.quit != nil {
+		close(self.quit)
+		self.quit = nil
+	}
+}
+
+// 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.
+func (self *Chequebook) Issue(beneficiary common.Address, amount *big.Int) (ch *Cheque, err error) {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+
+	if amount.Cmp(common.Big0) <= 0 {
+		return nil, fmt.Errorf("amount must be greater than zero (%v)", amount)
+	}
+	if self.balance.Cmp(amount) < 0 {
+		err = fmt.Errorf("insufficent funds to issue cheque for amount: %v. balance: %v", amount, self.balance)
+	} else {
+		var sig []byte
+		sent, found := self.sent[beneficiary]
+		if !found {
+			sent = new(big.Int)
+			self.sent[beneficiary] = sent
+		}
+		sum := new(big.Int).Set(sent)
+		sum.Add(sum, amount)
+
+		sig, err = crypto.Sign(sigHash(self.contractAddr, beneficiary, sum), self.prvKey)
+		if err == nil {
+			ch = &Cheque{
+				Contract:    self.contractAddr,
+				Beneficiary: beneficiary,
+				Amount:      sum,
+				Sig:         sig,
+			}
+			sent.Set(sum)
+			self.balance.Sub(self.balance, amount) // subtract amount from balance
+		}
+	}
+
+	// auto deposit if threshold is set and balance is less then threshold
+	// note this is called even if issueing cheque fails
+	// so we reattempt depositing
+	if self.threshold != nil {
+		if self.balance.Cmp(self.threshold) < 0 {
+			send := new(big.Int).Sub(self.buffer, self.balance)
+			self.deposit(send)
+		}
+	}
+
+	return
+}
+
+// Cash is a convenience method to cash any cheque.
+func (self *Chequebook) Cash(ch *Cheque) (txhash string, err error) {
+	return ch.Cash(self.session)
+}
+
+// data to sign: contract address, beneficiary, cumulative amount of funds ever sent
+func sigHash(contract, beneficiary common.Address, sum *big.Int) []byte {
+	bigamount := sum.Bytes()
+	if len(bigamount) > 32 {
+		return nil
+	}
+	var amount32 [32]byte
+	copy(amount32[32-len(bigamount):32], bigamount)
+	input := append(contract.Bytes(), beneficiary.Bytes()...)
+	input = append(input, amount32[:]...)
+	return crypto.Keccak256(input)
+}
+
+// Balance returns the current balance of the chequebook.
+func (self *Chequebook) Balance() *big.Int {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	return new(big.Int).Set(self.balance)
+}
+
+// Owner returns the owner account of the chequebook.
+func (self *Chequebook) Owner() common.Address {
+	return self.owner
+}
+
+// Address returns the on-chain contract address of the chequebook.
+func (self *Chequebook) Address() common.Address {
+	return self.contractAddr
+}
+
+// Deposit deposits money to the chequebook account.
+func (self *Chequebook) Deposit(amount *big.Int) (string, error) {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	return self.deposit(amount)
+}
+
+// deposit deposits amount to the chequebook account.
+// The caller must hold self.lock.
+func (self *Chequebook) deposit(amount *big.Int) (string, error) {
+	// since the amount is variable here, we do not use sessions
+	depositTransactor := bind.NewKeyedTransactor(self.prvKey)
+	depositTransactor.Value = amount
+	chbookRaw := &contract.ChequebookRaw{Contract: self.contract}
+	tx, err := chbookRaw.Transfer(depositTransactor)
+	if err != nil {
+		glog.V(logger.Warn).Infof("error depositing %d wei to chequebook (%s, balance: %v, target: %v): %v", amount, self.contractAddr.Hex(), self.balance, self.buffer, err)
+		return "", err
+	}
+	// assume that transaction is actually successful, we add the amount to balance right away
+	self.balance.Add(self.balance, amount)
+	glog.V(logger.Detail).Infof("deposited %d wei to chequebook (%s, balance: %v, target: %v)", amount, self.contractAddr.Hex(), self.balance, self.buffer)
+	return tx.Hash().Hex(), nil
+}
+
+// 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
+// deposit will be triggered on every new cheque issued.
+func (self *Chequebook) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	self.threshold = threshold
+	self.buffer = buffer
+	self.autoDeposit(interval)
+}
+
+// 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.
+func (self *Chequebook) autoDeposit(interval time.Duration) {
+	if self.quit != nil {
+		close(self.quit)
+		self.quit = nil
+	}
+	// 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 {
+		return
+	}
+
+	ticker := time.NewTicker(interval)
+	self.quit = make(chan bool)
+	quit := self.quit
+	go func() {
+	FOR:
+		for {
+			select {
+			case <-quit:
+				break FOR
+			case <-ticker.C:
+				self.lock.Lock()
+				if self.balance.Cmp(self.buffer) < 0 {
+					amount := new(big.Int).Sub(self.buffer, self.balance)
+					txhash, err := self.deposit(amount)
+					if err == nil {
+						self.txhash = txhash
+					}
+				}
+				self.lock.Unlock()
+			}
+		}
+	}()
+	return
+}
+
+// Outbox can issue cheques from a single contract to a single beneficiary.
+type Outbox struct {
+	chequeBook  *Chequebook
+	beneficiary common.Address
+}
+
+// NewOutbox creates an outbox.
+func NewOutbox(chbook *Chequebook, beneficiary common.Address) *Outbox {
+	return &Outbox{chbook, beneficiary}
+}
+
+// Issue creates cheque.
+func (self *Outbox) Issue(amount *big.Int) (interface{}, error) {
+	// TODO(fjl): the return type should be more descriptive.
+	return self.chequeBook.Issue(self.beneficiary, amount)
+}
+
+// AutoDeposit enables auto-deposits on the underlying chequebook.
+func (self *Outbox) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
+	self.chequeBook.AutoDeposit(interval, threshold, buffer)
+}
+
+// Stop helps satisfy the swap.OutPayment interface.
+func (self *Outbox) Stop() {}
+
+// String implements fmt.Stringer.
+func (self *Outbox) String() string {
+	return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", self.chequeBook.Address().Hex(), self.beneficiary.Hex(), self.chequeBook.Balance())
+}
+
+// Inbox can deposit, verify and cash cheques from a single contract to a single
+// beneficiary. It is the incoming payment handler for peer to peer micropayments.
+type Inbox struct {
+	lock        sync.Mutex
+	contract    common.Address              // peer's chequebook contract
+	beneficiary common.Address              // local peer's receiving address
+	sender      common.Address              // local peer's address to send cashing tx from
+	signer      *ecdsa.PublicKey            // peer's public key
+	txhash      string                      // tx hash of last cashing tx
+	abigen      bind.ContractBackend        // blockchain API
+	session     *contract.ChequebookSession // abi contract backend with tx opts
+	quit        chan bool                   // when closed causes autocash to stop
+	maxUncashed *big.Int                    // threshold that triggers autocashing
+	cashed      *big.Int                    // cumulative amount cashed
+	cheque      *Cheque                     // last cheque, nil if none yet received
+}
+
+// NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated
+// 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) {
+	if signer == nil {
+		return nil, fmt.Errorf("signer is null")
+	}
+	chbook, err := contract.NewChequebook(contractAddr, abigen)
+	if err != nil {
+		return nil, err
+	}
+	transactOpts := bind.NewKeyedTransactor(prvKey)
+	transactOpts.GasLimit = gasToCash
+	session := &contract.ChequebookSession{
+		Contract:     chbook,
+		TransactOpts: *transactOpts,
+	}
+	sender := transactOpts.From
+
+	self = &Inbox{
+		contract:    contractAddr,
+		beneficiary: beneficiary,
+		sender:      sender,
+		signer:      signer,
+		session:     session,
+		cashed:      new(big.Int).Set(common.Big0),
+	}
+	glog.V(logger.Detail).Infof("initialised inbox (%s -> %s) expected signer: %x", self.contract.Hex(), self.beneficiary.Hex(), crypto.FromECDSAPub(signer))
+	return
+}
+
+func (self *Inbox) String() string {
+	return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", self.contract.Hex(), self.beneficiary.Hex(), self.cheque.Amount)
+}
+
+// Stop quits the autocash goroutine.
+func (self *Inbox) Stop() {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	if self.quit != nil {
+		close(self.quit)
+		self.quit = nil
+	}
+}
+
+// Cash attempts to cash the current cheque.
+func (self *Inbox) Cash() (txhash string, err error) {
+	if self.cheque != nil {
+		txhash, err = self.cheque.Cash(self.session)
+		glog.V(logger.Detail).Infof("cashing cheque (total: %v) on chequebook (%s) sending to %v", self.cheque.Amount, self.contract.Hex(), self.beneficiary.Hex())
+		self.cashed = self.cheque.Amount
+	}
+	return
+}
+
+// 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.
+func (self *Inbox) AutoCash(cashInterval time.Duration, maxUncashed *big.Int) {
+	defer self.lock.Unlock()
+	self.lock.Lock()
+	self.maxUncashed = maxUncashed
+	self.autoCash(cashInterval)
+}
+
+// autoCash starts a loop that periodically clears the last check
+// if the peer is trusted. Clearing period could be 24h or a week.
+//
+// The caller must hold self.lock.
+func (self *Inbox) autoCash(cashInterval time.Duration) {
+	if self.quit != nil {
+		close(self.quit)
+		self.quit = nil
+	}
+	// if maxUncashed is set to 0, then autocash on receipt
+	if cashInterval == time.Duration(0) || self.maxUncashed != nil && self.maxUncashed.Cmp(common.Big0) == 0 {
+		return
+	}
+
+	ticker := time.NewTicker(cashInterval)
+	self.quit = make(chan bool)
+	quit := self.quit
+	go func() {
+	FOR:
+		for {
+			select {
+			case <-quit:
+				break FOR
+			case <-ticker.C:
+				self.lock.Lock()
+				if self.cheque != nil && self.cheque.Amount.Cmp(self.cashed) != 0 {
+					txhash, err := self.Cash()
+					if err == nil {
+						self.txhash = txhash
+					}
+				}
+				self.lock.Unlock()
+			}
+		}
+	}()
+	return
+}
+
+// Receive is called to deposit the latest cheque to the incoming Inbox.
+// The given promise must be a *Cheque.
+func (self *Inbox) Receive(promise interface{}) (*big.Int, error) {
+	// TODO(fjl): the type of promise should be safer
+	ch := promise.(*Cheque)
+
+	defer self.lock.Unlock()
+	self.lock.Lock()
+
+	var sum *big.Int
+	if self.cheque == nil {
+		// the sum is checked against the blockchain once a check is received
+		tally, err := self.session.Sent(self.beneficiary)
+		if err != nil {
+			return nil, fmt.Errorf("inbox: error 	calling backend to set amount: %v", err)
+		}
+		sum = tally
+	} else {
+		sum = self.cheque.Amount
+	}
+
+	amount, err := ch.Verify(self.signer, self.contract, self.beneficiary, sum)
+	var uncashed *big.Int
+	if err == nil {
+		self.cheque = ch
+
+		if self.maxUncashed != nil {
+			uncashed = new(big.Int).Sub(ch.Amount, self.cashed)
+			if self.maxUncashed.Cmp(uncashed) < 0 {
+				self.Cash()
+			}
+		}
+		glog.V(logger.Detail).Infof("received cheque of %v wei in inbox (%s, uncashed: %v)", amount, self.contract.Hex(), uncashed)
+	}
+
+	return amount, err
+}
+
+// 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) {
+	glog.V(logger.Detail).Infof("verify cheque: %v - sum: %v", self, sum)
+	if sum == nil {
+		return nil, fmt.Errorf("invalid amount")
+	}
+
+	if self.Beneficiary != beneficiary {
+		return nil, fmt.Errorf("beneficiary mismatch: %v != %v", self.Beneficiary.Hex(), beneficiary.Hex())
+	}
+	if self.Contract != contract {
+		return nil, fmt.Errorf("contract mismatch: %v != %v", self.Contract.Hex(), contract.Hex())
+	}
+
+	amount := new(big.Int).Set(self.Amount)
+	if sum != nil {
+		amount.Sub(amount, sum)
+		if amount.Cmp(common.Big0) <= 0 {
+			return nil, fmt.Errorf("incorrect amount: %v <= 0", amount)
+		}
+	}
+
+	pubKey, err := crypto.SigToPub(sigHash(self.Contract, beneficiary, self.Amount), self.Sig)
+	if err != nil {
+		return nil, fmt.Errorf("invalid signature: %v", err)
+	}
+	if !bytes.Equal(crypto.FromECDSAPub(pubKey), crypto.FromECDSAPub(signerKey)) {
+		return nil, fmt.Errorf("signer mismatch: %x != %x", crypto.FromECDSAPub(pubKey), crypto.FromECDSAPub(signerKey))
+	}
+	return amount, nil
+}
+
+// v/r/s representation of signature
+func sig2vrs(sig []byte) (v byte, r, s [32]byte) {
+	v = sig[64] + 27
+	copy(r[:], sig[:32])
+	copy(s[:], sig[32:64])
+	return
+}
+
+// Cash cashes the cheque by sending an Ethereum transaction.
+func (self *Cheque) Cash(session *contract.ChequebookSession) (string, error) {
+	v, r, s := sig2vrs(self.Sig)
+	tx, err := session.Cash(self.Beneficiary, self.Amount, v, r, s)
+	if err != nil {
+		return "", err
+	}
+	return tx.Hash().Hex(), nil
+}
+
+// ValidateCode checks that the on-chain code at address matches the expected chequebook
+// contract code. This is used to detect suicided chequebooks.
+func ValidateCode(ctx context.Context, b Backend, address common.Address) (ok bool, err error) {
+	code, err := b.CodeAt(ctx, address, nil)
+	if err != nil {
+		return false, err
+	}
+	return bytes.Equal(code, common.FromHex(contract.ContractDeployedCode)), nil
+}

+ 528 - 0
contracts/chequebook/cheque_test.go

@@ -0,0 +1,528 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package chequebook
+
+import (
+	"crypto/ecdsa"
+	"math/big"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+
+	"github.com/ethereum/go-ethereum/accounts/abi/bind"
+	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/contracts/chequebook/contract"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/crypto"
+)
+
+var (
+	key0, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+	key1, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
+	key2, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
+	addr0   = crypto.PubkeyToAddress(key0.PublicKey)
+	addr1   = crypto.PubkeyToAddress(key1.PublicKey)
+	addr2   = crypto.PubkeyToAddress(key2.PublicKey)
+)
+
+func newTestBackend() *backends.SimulatedBackend {
+	return backends.NewSimulatedBackend(
+		core.GenesisAccount{Address: addr0, Balance: big.NewInt(1000000000)},
+		core.GenesisAccount{Address: addr1, Balance: big.NewInt(1000000000)},
+		core.GenesisAccount{Address: addr2, Balance: big.NewInt(1000000000)},
+	)
+}
+
+func deploy(prvKey *ecdsa.PrivateKey, amount *big.Int, backend *backends.SimulatedBackend) (common.Address, error) {
+	deployTransactor := bind.NewKeyedTransactor(prvKey)
+	deployTransactor.Value = amount
+	addr, _, _, err := contract.DeployChequebook(deployTransactor, backend)
+	if err != nil {
+		return common.Address{}, err
+	}
+	backend.Commit()
+	return addr, nil
+}
+
+func TestIssueAndReceive(t *testing.T) {
+	path := filepath.Join(os.TempDir(), "chequebook-test.json")
+	backend := newTestBackend()
+	addr0, err := deploy(key0, big.NewInt(0), backend)
+	if err != nil {
+		t.Fatalf("deploy contract: expected no error, got %v", err)
+	}
+	chbook, err := NewChequebook(path, addr0, key0, backend)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	chbook.sent[addr1] = new(big.Int).SetUint64(42)
+	amount := common.Big1
+	ch, err := chbook.Issue(addr1, amount)
+	if err == nil {
+		t.Fatalf("expected insufficient funds error, got none")
+	}
+
+	chbook.balance = new(big.Int).Set(common.Big1)
+	if chbook.Balance().Cmp(common.Big1) != 0 {
+		t.Fatalf("expected: %v, got %v", "0", chbook.Balance())
+	}
+
+	ch, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	if chbook.Balance().Cmp(common.Big0) != 0 {
+		t.Errorf("expected: %v, got %v", "0", chbook.Balance())
+	}
+
+	chbox, err := NewInbox(key1, addr0, addr1, &key0.PublicKey, backend)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	received, err := chbox.Receive(ch)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	if received.Cmp(big.NewInt(43)) != 0 {
+		t.Errorf("expected: %v, got %v", "43", received)
+	}
+
+}
+
+func TestCheckbookFile(t *testing.T) {
+	path := filepath.Join(os.TempDir(), "chequebook-test.json")
+	backend := newTestBackend()
+	chbook, err := NewChequebook(path, addr0, key0, backend)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	chbook.sent[addr1] = new(big.Int).SetUint64(42)
+	chbook.balance = new(big.Int).Set(common.Big1)
+
+	chbook.Save()
+
+	chbook, err = LoadChequebook(path, key0, backend, false)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	if chbook.Balance().Cmp(common.Big1) != 0 {
+		t.Errorf("expected: %v, got %v", "0", chbook.Balance())
+	}
+
+	ch, err := chbook.Issue(addr1, common.Big1)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	if ch.Amount.Cmp(new(big.Int).SetUint64(43)) != 0 {
+		t.Errorf("expected: %v, got %v", "0", ch.Amount)
+	}
+
+	err = chbook.Save()
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+}
+
+func TestVerifyErrors(t *testing.T) {
+	path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json")
+	backend := newTestBackend()
+	contr0, err := deploy(key0, common.Big2, backend)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+	chbook0, err := NewChequebook(path0, contr0, key0, backend)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	path1 := filepath.Join(os.TempDir(), "chequebook-test-1.json")
+	contr1, err := deploy(key1, common.Big2, backend)
+	chbook1, err := NewChequebook(path1, contr1, key1, backend)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	chbook0.sent[addr1] = new(big.Int).SetUint64(42)
+	chbook0.balance = new(big.Int).Set(common.Big2)
+	chbook1.balance = new(big.Int).Set(common.Big1)
+	amount := common.Big1
+	ch0, err := chbook0.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	time.Sleep(5)
+	chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	received, err := chbox.Receive(ch0)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	if received.Cmp(big.NewInt(43)) != 0 {
+		t.Errorf("expected: %v, got %v", "43", received)
+	}
+
+	ch1, err := chbook0.Issue(addr2, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	received, err = chbox.Receive(ch1)
+	t.Logf("correct error: %v", err)
+	if err == nil {
+		t.Fatalf("expected receiver error, got none")
+	}
+
+	ch2, err := chbook1.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	received, err = chbox.Receive(ch2)
+	t.Logf("correct error: %v", err)
+	if err == nil {
+		t.Fatalf("expected sender error, got none")
+	}
+
+	_, err = chbook1.Issue(addr1, new(big.Int).SetInt64(-1))
+	t.Logf("correct error: %v", err)
+	if err == nil {
+		t.Fatalf("expected incorrect amount error, got none")
+	}
+
+	received, err = chbox.Receive(ch0)
+	t.Logf("correct error: %v", err)
+	if err == nil {
+		t.Fatalf("expected incorrect amount error, got none")
+	}
+
+}
+
+func TestDeposit(t *testing.T) {
+	path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json")
+	backend := newTestBackend()
+	contr0, err := deploy(key0, new(big.Int), backend)
+	chbook, err := NewChequebook(path0, contr0, key0, backend)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+
+	balance := new(big.Int).SetUint64(42)
+	chbook.Deposit(balance)
+	backend.Commit()
+	if chbook.balance.Cmp(balance) != 0 {
+		t.Fatalf("expected balance %v, got %v", balance, chbook.balance)
+	}
+
+	amount := common.Big1
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	exp := new(big.Int).SetUint64(41)
+	if chbook.balance.Cmp(exp) != 0 {
+		t.Fatalf("expected balance %v, got %v", exp, chbook.balance)
+	}
+
+	// autodeposit on each issue
+	chbook.AutoDeposit(0, balance, balance)
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	if chbook.balance.Cmp(balance) != 0 {
+		t.Fatalf("expected balance %v, got %v", balance, chbook.balance)
+	}
+
+	// autodeposit off
+	chbook.AutoDeposit(0, common.Big0, balance)
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	exp = new(big.Int).SetUint64(40)
+	if chbook.balance.Cmp(exp) != 0 {
+		t.Fatalf("expected balance %v, got %v", exp, chbook.balance)
+	}
+
+	// autodeposit every 10ms if new cheque issued
+	interval := 30 * time.Millisecond
+	chbook.AutoDeposit(interval, common.Big1, balance)
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	exp = new(big.Int).SetUint64(38)
+	if chbook.balance.Cmp(exp) != 0 {
+		t.Fatalf("expected balance %v, got %v", exp, chbook.balance)
+	}
+
+	time.Sleep(3 * interval)
+	backend.Commit()
+	if chbook.balance.Cmp(balance) != 0 {
+		t.Fatalf("expected balance %v, got %v", balance, chbook.balance)
+	}
+
+	exp = new(big.Int).SetUint64(40)
+	chbook.AutoDeposit(4*interval, exp, balance)
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	time.Sleep(3 * interval)
+	backend.Commit()
+	if chbook.balance.Cmp(exp) != 0 {
+		t.Fatalf("expected balance %v, got %v", exp, chbook.balance)
+	}
+
+	_, err = chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	time.Sleep(1 * interval)
+	backend.Commit()
+
+	if chbook.balance.Cmp(balance) != 0 {
+		t.Fatalf("expected balance %v, got %v", balance, chbook.balance)
+	}
+
+	chbook.AutoDeposit(1*interval, common.Big0, balance)
+	chbook.Stop()
+
+	_, err = chbook.Issue(addr1, common.Big1)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	_, err = chbook.Issue(addr1, common.Big2)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	time.Sleep(1 * interval)
+	backend.Commit()
+
+	exp = new(big.Int).SetUint64(39)
+	if chbook.balance.Cmp(exp) != 0 {
+		t.Fatalf("expected balance %v, got %v", exp, chbook.balance)
+	}
+
+}
+
+func TestCash(t *testing.T) {
+	path := filepath.Join(os.TempDir(), "chequebook-test.json")
+	backend := newTestBackend()
+	contr0, err := deploy(key0, common.Big2, backend)
+	chbook, err := NewChequebook(path, contr0, key0, backend)
+	if err != nil {
+		t.Errorf("expected no error, got %v", err)
+	}
+	chbook.sent[addr1] = new(big.Int).SetUint64(42)
+	amount := common.Big1
+	chbook.balance = new(big.Int).Set(common.Big1)
+	ch, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	// cashing latest cheque
+	_, err = chbox.Receive(ch)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	_, err = ch.Cash(chbook.session)
+	backend.Commit()
+
+	chbook.balance = new(big.Int).Set(common.Big3)
+	ch0, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	ch1, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	interval := 10 * time.Millisecond
+	// setting autocash with interval of 10ms
+	chbox.AutoCash(interval, nil)
+	_, err = chbox.Receive(ch0)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	_, err = chbox.Receive(ch1)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	// expBalance := big.NewInt(2)
+	// gotBalance := backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+	// after 3x interval time and 2 cheques received, exactly one cashing tx is sent
+	time.Sleep(4 * interval)
+	backend.Commit()
+
+	// expBalance = big.NewInt(4)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	// after stopping autocash no more tx are sent
+	ch2, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	chbox.Stop()
+	_, err = chbox.Receive(ch2)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	time.Sleep(2 * interval)
+	backend.Commit()
+	// expBalance = big.NewInt(4)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	// autocash below 1
+	chbook.balance = big.NewInt(2)
+	chbox.AutoCash(0, common.Big1)
+
+	ch3, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	// expBalance = big.NewInt(4)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	ch4, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	_, err = chbox.Receive(ch3)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	_, err = chbox.Receive(ch4)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+
+	// 2 checks of amount 1 received, exactly 1 tx is sent
+	// expBalance = big.NewInt(6)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	// autochash on receipt when maxUncashed is 0
+	chbook.balance = new(big.Int).Set(common.Big2)
+	chbox.AutoCash(0, common.Big0)
+
+	ch5, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	// expBalance = big.NewInt(5)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	ch6, err := chbook.Issue(addr1, amount)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+
+	_, err = chbox.Receive(ch5)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	// expBalance = big.NewInt(4)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+	_, err = chbox.Receive(ch6)
+	if err != nil {
+		t.Fatalf("expected no error, got %v", err)
+	}
+	backend.Commit()
+	// expBalance = big.NewInt(6)
+	// gotBalance = backend.BalanceAt(addr1)
+	// if gotBalance.Cmp(expBalance) != 0 {
+	// 	t.Fatalf("expected beneficiary balance %v, got %v", expBalance, gotBalance)
+	// }
+
+}

+ 554 - 0
contracts/chequebook/contract/chequebook.go

@@ -0,0 +1,554 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package contract
+
+import (
+	"math/big"
+	"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"
+)
+
+// ChequebookABI is the input ABI used to generate the binding from.
+const ChequebookABI = `[{"constant":false,"inputs":[],"name":"kill","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"sent","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"},{"name":"sig_v","type":"uint8"},{"name":"sig_r","type":"bytes32"},{"name":"sig_s","type":"bytes32"}],"name":"cash","outputs":[],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"deadbeat","type":"address"}],"name":"Overdraft","type":"event"}]`
+
+// ChequebookBin is the compiled bytecode used for deploying new contracts.
+const ChequebookBin = `0x606060405260008054600160a060020a03191633179055610223806100246000396000f3606060405260e060020a600035046341c0e1b581146100315780637bf786f814610059578063fbf788d614610071575b005b61002f60005433600160a060020a03908116911614156100b957600054600160a060020a0316ff5b6100a760043560016020526000908152604090205481565b61002f600435602435604435606435608435600160a060020a03851660009081526001602052604081205485116100bb576101cf565b60408051918252519081900360200190f35b565b50604080516c0100000000000000000000000030600160a060020a0390811682028352881602601482015260288101869052815190819003604801812080825260ff861660208381019190915282840186905260608301859052925190926001926080818101939182900301816000866161da5a03f11561000257505060405151600054600160a060020a03908116911614610156576101cf565b600160a060020a038681166000908152600160205260409020543090911631908603106101d75760406000818120549151600160a060020a0389169288039082818181858883f19350505050156101cf57846001600050600088600160a060020a03168152602001908152602001600020600050819055505b505050505050565b60005460408051600160a060020a03929092168252517f2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f9789181900360200190a185600160a060020a0316ff`
+
+// DeployChequebook deploys a new Ethereum contract, binding an instance of Chequebook to it.
+func DeployChequebook(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Chequebook, error) {
+	parsed, err := abi.JSON(strings.NewReader(ChequebookABI))
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ChequebookBin), backend)
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	return address, tx, &Chequebook{ChequebookCaller: ChequebookCaller{contract: contract}, ChequebookTransactor: ChequebookTransactor{contract: contract}}, nil
+}
+
+// Chequebook is an auto generated Go binding around an Ethereum contract.
+type Chequebook struct {
+	ChequebookCaller     // Read-only binding to the contract
+	ChequebookTransactor // Write-only binding to the contract
+}
+
+// ChequebookCaller is an auto generated read-only Go binding around an Ethereum contract.
+type ChequebookCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ChequebookTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type ChequebookTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ChequebookSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ChequebookSession struct {
+	Contract     *Chequebook       // 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
+}
+
+// ChequebookCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ChequebookCallerSession struct {
+	Contract *ChequebookCaller // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts     // Call options to use throughout this session
+}
+
+// ChequebookTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ChequebookTransactorSession struct {
+	Contract     *ChequebookTransactor // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts     // Transaction auth options to use throughout this session
+}
+
+// ChequebookRaw is an auto generated low-level Go binding around an Ethereum contract.
+type ChequebookRaw struct {
+	Contract *Chequebook // Generic contract binding to access the raw methods on
+}
+
+// ChequebookCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ChequebookCallerRaw struct {
+	Contract *ChequebookCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// ChequebookTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ChequebookTransactorRaw struct {
+	Contract *ChequebookTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewChequebook creates a new instance of Chequebook, bound to a specific deployed contract.
+func NewChequebook(address common.Address, backend bind.ContractBackend) (*Chequebook, error) {
+	contract, err := bindChequebook(address, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &Chequebook{ChequebookCaller: ChequebookCaller{contract: contract}, ChequebookTransactor: ChequebookTransactor{contract: contract}}, nil
+}
+
+// NewChequebookCaller creates a new read-only instance of Chequebook, bound to a specific deployed contract.
+func NewChequebookCaller(address common.Address, caller bind.ContractCaller) (*ChequebookCaller, error) {
+	contract, err := bindChequebook(address, caller, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &ChequebookCaller{contract: contract}, nil
+}
+
+// NewChequebookTransactor creates a new write-only instance of Chequebook, bound to a specific deployed contract.
+func NewChequebookTransactor(address common.Address, transactor bind.ContractTransactor) (*ChequebookTransactor, error) {
+	contract, err := bindChequebook(address, nil, transactor)
+	if err != nil {
+		return nil, err
+	}
+	return &ChequebookTransactor{contract: contract}, nil
+}
+
+// bindChequebook binds a generic wrapper to an already deployed contract.
+func bindChequebook(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) {
+	parsed, err := abi.JSON(strings.NewReader(ChequebookABI))
+	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 (_Chequebook *ChequebookRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Chequebook.Contract.ChequebookCaller.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 (_Chequebook *ChequebookRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Chequebook.Contract.ChequebookTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Chequebook *ChequebookRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Chequebook.Contract.ChequebookTransactor.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 (_Chequebook *ChequebookCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Chequebook.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 (_Chequebook *ChequebookTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Chequebook.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Chequebook *ChequebookTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Chequebook.Contract.contract.Transact(opts, method, params...)
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookCaller) Sent(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) {
+	var (
+		ret0 = new(*big.Int)
+	)
+	out := ret0
+	err := _Chequebook.contract.Call(opts, out, "sent", arg0)
+	return *ret0, err
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookSession) Sent(arg0 common.Address) (*big.Int, error) {
+	return _Chequebook.Contract.Sent(&_Chequebook.CallOpts, arg0)
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookCallerSession) Sent(arg0 common.Address) (*big.Int, error) {
+	return _Chequebook.Contract.Sent(&_Chequebook.CallOpts, arg0)
+}
+
+// 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()
+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) {
+	return _Chequebook.contract.Transact(opts, "cash", beneficiary, amount, sig_v, sig_r, sig_s)
+}
+
+// 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()
+func (_Chequebook *ChequebookSession) Cash(beneficiary common.Address, amount *big.Int, sig_v uint8, sig_r [32]byte, sig_s [32]byte) (*types.Transaction, error) {
+	return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sig_v, sig_r, sig_s)
+}
+
+// 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()
+func (_Chequebook *ChequebookTransactorSession) Cash(beneficiary common.Address, amount *big.Int, sig_v uint8, sig_r [32]byte, sig_s [32]byte) (*types.Transaction, error) {
+	return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sig_v, sig_r, sig_s)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookTransactor) Kill(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Chequebook.contract.Transact(opts, "kill")
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookSession) Kill() (*types.Transaction, error) {
+	return _Chequebook.Contract.Kill(&_Chequebook.TransactOpts)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookTransactorSession) Kill() (*types.Transaction, error) {
+	return _Chequebook.Contract.Kill(&_Chequebook.TransactOpts)
+}
+
+// MortalABI is the input ABI used to generate the binding from.
+const MortalABI = `[{"constant":false,"inputs":[],"name":"kill","outputs":[],"type":"function"}]`
+
+// MortalBin is the compiled bytecode used for deploying new contracts.
+const MortalBin = `0x606060405260008054600160a060020a03191633179055605c8060226000396000f3606060405260e060020a600035046341c0e1b58114601a575b005b60186000543373ffffffffffffffffffffffffffffffffffffffff90811691161415605a5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b56`
+
+// DeployMortal deploys a new Ethereum contract, binding an instance of Mortal to it.
+func DeployMortal(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Mortal, error) {
+	parsed, err := abi.JSON(strings.NewReader(MortalABI))
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(MortalBin), backend)
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	return address, tx, &Mortal{MortalCaller: MortalCaller{contract: contract}, MortalTransactor: MortalTransactor{contract: contract}}, nil
+}
+
+// Mortal is an auto generated Go binding around an Ethereum contract.
+type Mortal struct {
+	MortalCaller     // Read-only binding to the contract
+	MortalTransactor // Write-only binding to the contract
+}
+
+// MortalCaller is an auto generated read-only Go binding around an Ethereum contract.
+type MortalCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// MortalTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type MortalTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// MortalSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type MortalSession struct {
+	Contract     *Mortal           // 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
+}
+
+// MortalCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type MortalCallerSession struct {
+	Contract *MortalCaller // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// MortalTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type MortalTransactorSession struct {
+	Contract     *MortalTransactor // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// MortalRaw is an auto generated low-level Go binding around an Ethereum contract.
+type MortalRaw struct {
+	Contract *Mortal // Generic contract binding to access the raw methods on
+}
+
+// MortalCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type MortalCallerRaw struct {
+	Contract *MortalCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// MortalTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type MortalTransactorRaw struct {
+	Contract *MortalTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewMortal creates a new instance of Mortal, bound to a specific deployed contract.
+func NewMortal(address common.Address, backend bind.ContractBackend) (*Mortal, error) {
+	contract, err := bindMortal(address, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &Mortal{MortalCaller: MortalCaller{contract: contract}, MortalTransactor: MortalTransactor{contract: contract}}, nil
+}
+
+// NewMortalCaller creates a new read-only instance of Mortal, bound to a specific deployed contract.
+func NewMortalCaller(address common.Address, caller bind.ContractCaller) (*MortalCaller, error) {
+	contract, err := bindMortal(address, caller, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &MortalCaller{contract: contract}, nil
+}
+
+// NewMortalTransactor creates a new write-only instance of Mortal, bound to a specific deployed contract.
+func NewMortalTransactor(address common.Address, transactor bind.ContractTransactor) (*MortalTransactor, error) {
+	contract, err := bindMortal(address, nil, transactor)
+	if err != nil {
+		return nil, err
+	}
+	return &MortalTransactor{contract: contract}, nil
+}
+
+// bindMortal binds a generic wrapper to an already deployed contract.
+func bindMortal(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) {
+	parsed, err := abi.JSON(strings.NewReader(MortalABI))
+	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 (_Mortal *MortalRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Mortal.Contract.MortalCaller.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 (_Mortal *MortalRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Mortal.Contract.MortalTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Mortal *MortalRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Mortal.Contract.MortalTransactor.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 (_Mortal *MortalCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Mortal.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 (_Mortal *MortalTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Mortal.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Mortal *MortalTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Mortal.Contract.contract.Transact(opts, method, params...)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Mortal *MortalTransactor) Kill(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Mortal.contract.Transact(opts, "kill")
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Mortal *MortalSession) Kill() (*types.Transaction, error) {
+	return _Mortal.Contract.Kill(&_Mortal.TransactOpts)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Mortal *MortalTransactorSession) Kill() (*types.Transaction, error) {
+	return _Mortal.Contract.Kill(&_Mortal.TransactOpts)
+}
+
+// OwnedABI is the input ABI used to generate the binding from.
+const OwnedABI = `[{"inputs":[],"type":"constructor"}]`
+
+// OwnedBin is the compiled bytecode used for deploying new contracts.
+const OwnedBin = `0x606060405260008054600160a060020a0319163317905560068060226000396000f3606060405200`
+
+// DeployOwned deploys a new Ethereum contract, binding an instance of Owned to it.
+func DeployOwned(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Owned, error) {
+	parsed, err := abi.JSON(strings.NewReader(OwnedABI))
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(OwnedBin), backend)
+	if err != nil {
+		return common.Address{}, nil, nil, err
+	}
+	return address, tx, &Owned{OwnedCaller: OwnedCaller{contract: contract}, OwnedTransactor: OwnedTransactor{contract: contract}}, nil
+}
+
+// Owned is an auto generated Go binding around an Ethereum contract.
+type Owned struct {
+	OwnedCaller     // Read-only binding to the contract
+	OwnedTransactor // Write-only binding to the contract
+}
+
+// OwnedCaller is an auto generated read-only Go binding around an Ethereum contract.
+type OwnedCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// OwnedTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type OwnedTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// OwnedSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type OwnedSession struct {
+	Contract     *Owned            // 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
+}
+
+// OwnedCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type OwnedCallerSession struct {
+	Contract *OwnedCaller  // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// OwnedTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type OwnedTransactorSession struct {
+	Contract     *OwnedTransactor  // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// OwnedRaw is an auto generated low-level Go binding around an Ethereum contract.
+type OwnedRaw struct {
+	Contract *Owned // Generic contract binding to access the raw methods on
+}
+
+// OwnedCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type OwnedCallerRaw struct {
+	Contract *OwnedCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// OwnedTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type OwnedTransactorRaw struct {
+	Contract *OwnedTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewOwned creates a new instance of Owned, bound to a specific deployed contract.
+func NewOwned(address common.Address, backend bind.ContractBackend) (*Owned, error) {
+	contract, err := bindOwned(address, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &Owned{OwnedCaller: OwnedCaller{contract: contract}, OwnedTransactor: OwnedTransactor{contract: contract}}, nil
+}
+
+// NewOwnedCaller creates a new read-only instance of Owned, bound to a specific deployed contract.
+func NewOwnedCaller(address common.Address, caller bind.ContractCaller) (*OwnedCaller, error) {
+	contract, err := bindOwned(address, caller, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &OwnedCaller{contract: contract}, nil
+}
+
+// NewOwnedTransactor creates a new write-only instance of Owned, bound to a specific deployed contract.
+func NewOwnedTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnedTransactor, error) {
+	contract, err := bindOwned(address, nil, transactor)
+	if err != nil {
+		return nil, err
+	}
+	return &OwnedTransactor{contract: contract}, nil
+}
+
+// bindOwned binds a generic wrapper to an already deployed contract.
+func bindOwned(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) {
+	parsed, err := abi.JSON(strings.NewReader(OwnedABI))
+	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 (_Owned *OwnedRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Owned.Contract.OwnedCaller.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 (_Owned *OwnedRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Owned.Contract.OwnedTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Owned *OwnedRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Owned.Contract.OwnedTransactor.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 (_Owned *OwnedCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+	return _Owned.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 (_Owned *OwnedTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _Owned.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Owned *OwnedTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _Owned.Contract.contract.Transact(opts, method, params...)
+}

+ 43 - 0
contracts/chequebook/contract/chequebook.sol

@@ -0,0 +1,43 @@
+import "mortal";
+
+/// @title Chequebook for Ethereum micropayments
+/// @author Daniel A. Nagy <daniel@ethdev.com>
+contract chequebook is mortal {
+    // Cumulative paid amount in wei to each beneficiary
+    mapping (address => uint256) public sent;
+
+    /// @notice Overdraft event
+    event Overdraft(address deadbeat);
+
+    /// @notice Cash cheque
+    ///
+    /// @param beneficiary beneficiary address
+    /// @param amount cumulative amount in wei
+    /// @param sig_v signature parameter v
+    /// @param sig_r signature parameter r
+    /// @param sig_s signature parameter s
+    /// The digital signature is calculated on the concatenated triplet of contract address, beneficiary address and cumulative amount
+    function cash(address beneficiary, uint256 amount,
+        uint8 sig_v, bytes32 sig_r, bytes32 sig_s) {
+        // Check if the cheque is old.
+        // Only cheques that are more recent than the last cashed one are considered.
+        if(amount <= sent[beneficiary]) return;
+        // Check the digital signature of the cheque.
+        bytes32 hash = sha3(address(this), beneficiary, amount);
+        if(owner != ecrecover(hash, sig_v, sig_r, sig_s)) return;
+        // Attempt sending the difference between the cumulative amount on the cheque
+        // and the cumulative amount on the last cashed cheque to beneficiary.
+        if (amount - sent[beneficiary] >= this.balance) {
+            if (beneficiary.send(amount - sent[beneficiary])) {
+                // Upon success, update the cumulative amount.
+                sent[beneficiary] = amount;
+            }
+        } else {
+            // Upon failure, punish owner for writing a bounced cheque.
+            // owner.sendToDebtorsPrison();
+            Overdraft(owner);
+            // Compensate beneficiary.
+            suicide(beneficiary);
+        }
+    }
+}

+ 21 - 0
contracts/chequebook/contract/code.go

@@ -0,0 +1,21 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package contract
+
+// ContractDeployedCode is used to detect suicides. This constant needs to be
+// updated when the contract code is changed.
+const ContractDeployedCode = "0x606060405260e060020a600035046341c0e1b581146100315780637bf786f814610059578063fbf788d614610071575b005b61002f60005433600160a060020a03908116911614156100b957600054600160a060020a0316ff5b6100a760043560016020526000908152604090205481565b61002f600435602435604435606435608435600160a060020a03851660009081526001602052604081205485116100bb576101cf565b60408051918252519081900360200190f35b565b50604080516c0100000000000000000000000030600160a060020a0390811682028352881602601482015260288101869052815190819003604801812080825260ff861660208381019190915282840186905260608301859052925190926001926080818101939182900301816000866161da5a03f11561000257505060405151600054600160a060020a03908116911614610156576101cf565b600160a060020a038681166000908152600160205260409020543090911631908603106101d75760406000818120549151600160a060020a0389169288039082818181858883f19350505050156101cf57846001600050600088600160a060020a03168152602001908152602001600020600050819055505b505050505050565b60005460408051600160a060020a03929092168252517f2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f9789181900360200190a185600160a060020a0316ff"

+ 73 - 0
contracts/chequebook/gencode.go

@@ -0,0 +1,73 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// +build none
+
+// This program generates contract/code.go, which contains the chequebook code
+// after deployment.
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/accounts/abi/bind"
+	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+	"github.com/ethereum/go-ethereum/contracts/chequebook/contract"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/crypto"
+)
+
+var (
+	testKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+	testAccount = core.GenesisAccount{
+		Address: crypto.PubkeyToAddress(testKey.PublicKey),
+		Balance: big.NewInt(500000000000),
+	}
+)
+
+func main() {
+	backend := backends.NewSimulatedBackend(testAccount)
+	auth := bind.NewKeyedTransactor(testKey)
+
+	// Deploy the contract, get the code.
+	addr, _, _, err := contract.DeployChequebook(auth, backend)
+	if err != nil {
+		panic(err)
+	}
+	backend.Commit()
+	code, err := backend.CodeAt(nil, addr, nil)
+	if err != nil {
+		panic(err)
+	}
+	if len(code) == 0 {
+		panic("empty code")
+	}
+
+	// Write the output file.
+	content := fmt.Sprintf(`// TODO: insert license header
+
+package contract
+
+// ContractDeployedCode is used to detect suicides. This constant needs to be
+// updated when the contract code is changed.
+const ContractDeployedCode = "%#x"
+`, code)
+	if err := ioutil.WriteFile("contract/code.go", []byte(content), 0644); err != nil {
+		panic(err)
+	}
+}