// Call forms a transaction from the given arguments and tries to execute it on // a private VM with a copy of the state. Any changes are therefore only temporary // and not part of the actual state. This allows for local execution/queries. func (be *registryAPIBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { block := be.bc.CurrentBlock() statedb, err := state.New(block.Root(), be.chainDb) if err != nil { return "", "", err } var from *state.StateObject if len(fromStr) == 0 { accounts, err := be.am.Accounts() if err != nil || len(accounts) == 0 { from = statedb.GetOrNewStateObject(common.Address{}) } else { from = statedb.GetOrNewStateObject(accounts[0].Address) } } else { from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) } from.SetBalance(common.MaxBig) msg := callmsg{ from: from, gas: common.Big(gasStr), gasPrice: common.Big(gasPriceStr), value: common.Big(valueStr), data: common.FromHex(dataStr), } if len(toStr) > 0 { addr := common.HexToAddress(toStr) msg.to = &addr } if msg.gas.Cmp(big.NewInt(0)) == 0 { msg.gas = big.NewInt(50000000) } if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) } header := be.bc.CurrentBlock().Header() vmenv := core.NewEnv(statedb, be.bc, msg, header) gp := new(core.GasPool).AddGas(common.MaxBig) res, gas, err := core.ApplyMessage(vmenv, msg, gp) return common.ToHex(res), gas.String(), err }
// MakeAddress converts an account specified directly as a hex encoded string or // a key index in the key store to an internal account representation. func MakeAddress(accman *accounts.Manager, account string) (a common.Address, err error) { // If the specified account is a valid address, return it if common.IsHexAddress(account) { return common.HexToAddress(account), nil } // Otherwise try to interpret the account as a keystore index index, err := strconv.Atoi(account) if err != nil { return a, fmt.Errorf("invalid account address or index %q", account) } hex, err := accman.AddressByIndex(index) if err != nil { return a, fmt.Errorf("can't get account #%d (%v)", index, err) } return common.HexToAddress(hex), nil }
// StorageAt returns the data stores in the state for the given address and location. func (be *registryAPIBackend) StorageAt(addr string, storageAddr string) string { block := be.bc.CurrentBlock() state, err := state.New(block.Root(), be.chainDb) if err != nil { return "" } return state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex() }
// Store inserts a new authorized payment into the account vault for later // redemption. func (v *accountVault) Store(auth *authorization) { v.lock.Lock() defer v.lock.Unlock() consumer := common.HexToAddress(auth.Consumer) v.auths[consumer] = auth v.pends[consumer] = auth }
func (s *Ethereum) Etherbase() (eb common.Address, err error) { eb = s.etherbase if (eb == common.Address{}) { addr, e := s.AccountManager().AddressByIndex(0) if e != nil { err = fmt.Errorf("etherbase address must be explicitly specified") } eb = common.HexToAddress(addr) } return }
// Charge will redeem all pending payments made to this provider since startup. func (v *accountVault) Charge(charger Charger) { v.lock.RLock() for _, auth := range v.pends { tx, err := charger.Charge(common.HexToAddress(auth.Consumer), common.HexToAddress(auth.Provider), auth.Nonce, new(big.Int).SetUint64(auth.Amount), common.FromHex(auth.Signature)) if err != nil { log15.Error("Failed to charge payment", "authorization", auth, "error", err) } else { log15.Info("Payment charged", "tx", "http://testnet.etherscan.io/tx/"+tx.Hex()) } } v.lock.RUnlock() v.lock.Lock() for consumer, auth := range v.auths { if v.pends[consumer] == auth { delete(v.pends, consumer) } } v.lock.Unlock() }
// Store inserts a new authorized payment into the vault for later redemption. func (v *Vault) Store(auth *authorization) { v.lock.Lock() defer v.lock.Unlock() provider := common.HexToAddress(auth.Provider) if _, ok := v.vaults[provider]; !ok { v.vaults[provider] = &accountVault{ auths: make(map[common.Address]*authorization), pends: make(map[common.Address]*authorization), } } v.vaults[provider].Store(auth) }
// NameToAddr(from, name) queries the registrar for the address on name func (self *Registrar) NameToAddr(from common.Address, name string) (address common.Address, err error) { if zero.MatchString(GlobalRegistrarAddr) { return address, fmt.Errorf("GlobalRegistrar address is not set") } nameHex, extra := encodeName(name, 2) abi := resolveAbi + nameHex + extra glog.V(logger.Detail).Infof("NameToAddr data: %s", abi) res, _, err := self.backend.Call( from.Hex(), GlobalRegistrarAddr, "", "", "", abi, ) if err != nil { return } address = common.HexToAddress(res) return }
func (h *Header) UnmarshalJSON(data []byte) error { var ext struct { ParentHash string Coinbase string Difficulty string GasLimit string Time *big.Int Extra string } dec := json.NewDecoder(bytes.NewReader(data)) if err := dec.Decode(&ext); err != nil { return err } h.ParentHash = common.HexToHash(ext.ParentHash) h.Coinbase = common.HexToAddress(ext.Coinbase) h.Difficulty = common.String2Big(ext.Difficulty) h.Time = ext.Time h.Extra = []byte(ext.Extra) return nil }
// ServeHTTP implements http.Handler, extracting and validating payment headers // contained within the HTTP request. If payment information is accepted, the // request is passed on to the internal service for execution. Otherwise the proxy // short circuits the request and sends back an appropriate error. func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { reqLogger := p.logger.New("request-id", atomic.AddUint32(&p.autoid, 1)) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Expose-Headers", VerificationHeader) // Short circuit CORS pre-flight requests if r.Method == "OPTIONS" { reqLogger.Debug("Allowing CORS pre-flight request") w.Header().Set("Access-Control-Allow-Headers", r.Header.Get("Access-Control-Request-Headers")) return } // Allow head requests through for data APIs to query the content size if r.Method == "HEAD" { reqLogger.Debug("Allowing data HEAD request") w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Content-Range") res, err := p.service(r) if err != nil { reqLogger.Error("Failed to process API request", "error", err) http.Error(w, "Failed to execute request", http.StatusInternalServerError) return } defer res.Body.Close() p.forward(w, res) return } // Retrieve the authorization header from the original request authHeader := r.Header.Get(AuthorizationHeader) reqLogger.Debug("Received an API request", "authorization", authHeader) // Ensure that all payment information are present if authHeader == "" { p.fail(w, &verification{Error: "Missing HTTP header: " + AuthorizationHeader}) return } auth := new(authorization) if err := json.Unmarshal([]byte(authHeader), auth); err != nil { p.fail(w, &verification{Error: "Invalid authorization header: " + err.Error()}) return } // Process the request and payment based on the proxy type switch p.kind { case CallProxy: // Make sure the consumer authorized the payment for this call consumer, provider := common.HexToAddress(auth.Consumer), common.HexToAddress(auth.Provider) if !p.verifier.Exists(consumer, provider) { p.fail(w, &verification{Unknown: true, Error: "Non existent API subscription"}) return } nonce := p.verifier.Nonce(consumer, provider).Uint64() if auth.Nonce != nonce { p.fail(w, &verification{Error: "Invalid nonce", Nonce: nonce}) return } valid, funded := p.verifier.Verify(consumer, provider, auth.Nonce, new(big.Int).SetUint64(auth.Amount), common.FromHex(auth.Signature)) if !valid { p.fail(w, &verification{Error: "Invalid authorization signature"}) return } if !funded { p.fail(w, &verification{Error: "Not enough funds available"}) return } price := p.verifier.Price(consumer, provider).Uint64() if prev := p.vault.Fetch(provider, consumer); prev != nil && prev.Amount+price > auth.Amount { p.fail(w, &verification{ Error: "Not enough funds authorized", Authorized: prev.Amount, Proof: prev.Signature, Need: prev.Amount + price, }) return } p.vault.Store(auth) // Execute the API internally and proxy the response reqLogger.Debug("Payment accepted for API invocation") res, err := p.service(r) if err != nil { reqLogger.Error("Failed to process API request", "error", err) http.Error(w, "Failed to execute request", http.StatusInternalServerError) return } defer res.Body.Close() p.forward(w, res) case DataProxy: // Since we're paying by the data, retrieve the amount first res, err := p.service(r) if err != nil { reqLogger.Error("Failed to process API request", "error", err) http.Error(w, "Failed to execute request", http.StatusInternalServerError) return } defer res.Body.Close() // Make sure the user authorized payment for all the requested data data := res.ContentLength if data > 0 /* TODO */ { reqLogger.Debug("Payment accepted for API stream", "data", data) p.forward(w, res) } } }
func main() { // Parse and handle the command line flags flag.Parse() log15.Root().SetHandler(log15.LvlFilterHandler(log15.Lvl(*loglevelFlag), log15.StderrHandler)) datadir := *datadirFlag if datadir == "" { datadir = filepath.Join(os.Getenv("HOME"), ".etherapis") } if err := os.MkdirAll(datadir, 0700); err != nil { log15.Crit("Failed to create data directory: %v", err) return } // Assemble and start the Ethereum client log15.Info("Booting Ethereum client...") client, err := geth.New(datadir, geth.TestNet) if err != nil { log15.Crit("Failed to create Ethereum client", "error", err) return } if err := client.Start(); err != nil { log15.Crit("Failed to start Ethereum client", "error", err) return } api, err := client.Attach() if err != nil { log15.Crit("Failed to attach to node", "error", err) return } // Wait for network connectivity and monitor synchronization log15.Info("Searching for network peers...") server := client.Stack().Server() for len(server.Peers()) == 0 { time.Sleep(100 * time.Millisecond) } go monitorSync(api) // Make sure we're at least semi recent on the chain before continuing waitSync(*syncFlag, api) var eth *eth.Ethereum err = client.Stack().Service(ð) if err != nil { log15.Crit("Failed to fetch eth service", "error", err) return } contract, err := channels.Fetch(eth.ChainDb(), eth.EventMux(), eth.BlockChain()) if err != nil { log15.Crit("Failed to get contract", "error", err) return } // Depending on the flags, execute different things switch { case *signFlag != "": var message struct { Provider string Nonce uint64 Amount uint64 } if err := json.Unmarshal([]byte(*signFlag), &message); err != nil { log15.Crit("Failed to decode data", "error", err) return } fmt.Println(message) accounts, err := eth.AccountManager().Accounts() if err != nil { log15.Crit("Failed retrieving accounts", "err", err) } if len(accounts) == 0 { log15.Crit("Signing data requires at least one account", "len", len(accounts)) return } account := accounts[0] from := account.Address to := common.HexToAddress(message.Provider) hash := contract.Call("getHash", from, to, message.Nonce, message.Amount).([]byte) log15.Info("getting hash", "hash", common.ToHex(hash)) eth.AccountManager().Unlock(from, "") sig, err := eth.AccountManager().Sign(account, hash) if err != nil { log15.Crit("signing vailed", "err", err) return } log15.Info("generated signature", "sig", common.ToHex(sig)) return case *importFlag != "": // Account import, parse the provided .json file and ensure it's proper manager := eth.AccountManager() account, err := manager.Import(*importFlag, "") if err != nil { log15.Crit("Failed to import specified account", "path", *importFlag, "error", err) return } state, _ := eth.BlockChain().State() log15.Info("Account successfully imported", "account", fmt.Sprintf("0x%x", account.Address), "balance", state.GetBalance(account.Address)) return case *accountsFlag: // Account listing requested, print all accounts and balances accounts, err := eth.AccountManager().Accounts() if err != nil || len(accounts) == 0 { log15.Crit("Failed to retrieve account", "accounts", len(accounts), "error", err) return } state, _ := eth.BlockChain().State() for i, account := range accounts { balance := float64(new(big.Int).Div(state.GetBalance(account.Address), common.Finney).Int64()) / 1000 fmt.Printf("Account #%d: %f ether (http://testnet.etherscan.io/address/0x%x)\n", i, balance, account.Address) } return case *accGenFlag > 0: // We're generating and dumping demo accounts var nonce uint64 var bank accounts.Account if *accLiveFlag { // If we want to fund generated accounts, make sure we can accounts, err := eth.AccountManager().Accounts() if err != nil || len(accounts) == 0 { log15.Crit("Failed to retrieve funding account", "accounts", len(accounts), "error", err) return } bank = accounts[0] if err := eth.AccountManager().Unlock(bank.Address, "gophergala"); err != nil { log15.Crit("Failed to unlock funding account", "account", fmt.Sprintf("0x%x", bank.Address), "error", err) return } state, _ := eth.BlockChain().State() nonce = state.GetNonce(bank.Address) log15.Info("Funding demo accounts with", "bank", fmt.Sprintf("0x%x", bank.Address), "nonce", nonce) } // Start generating the actual accounts log15.Info("Generating demo accounts", "count", *accGenFlag) for i := 0; i < *accGenFlag; i++ { // Generate a new account account, err := eth.AccountManager().NewAccount("pass") if err != nil { log15.Crit("Failed to generate new account", "error", err) return } // Export it's private key keyPath := fmt.Sprintf("0x%x.key", account.Address) if err := eth.AccountManager().Export(keyPath, account.Address, "pass"); err != nil { log15.Crit("Failed to export account", "account", fmt.Sprintf("0x%x", account.Address), "error", err) return } // Clean up so it doesn't clutter out accounts if err := eth.AccountManager().DeleteAccount(account.Address, "pass"); err != nil { log15.Crit("Failed to delete account", "account", fmt.Sprintf("0x%x", account.Address), "error", err) return } // If we're just testing, stop here if !*accLiveFlag { log15.Info("Account generated and exported", "path", keyPath) continue } // Oh boy, live accounts, send some ether to it and upload to the faucet allowance := new(big.Int).Mul(big.NewInt(10), common.Ether) price := new(big.Int).Mul(big.NewInt(50), common.Shannon) tx := types.NewTransaction(nonce, account.Address, allowance, big.NewInt(21000), price, nil) sig, err := eth.AccountManager().Sign(bank, tx.SigHash().Bytes()) if err != nil { log15.Crit("Failed to sign funding transaction", "error", err) return } stx, err := tx.WithSignature(sig) if err != nil { log15.Crit("Failed to assemble funding transaction", "error", err) return } if err := eth.TxPool().Add(stx); err != nil { log15.Crit("Failed to execute transfer", "error", err) return } nonce++ log15.Info("Account successfully funded", "account", fmt.Sprintf("0x%x", account.Address)) // Upload the account to the faucet server key, err := ioutil.ReadFile(keyPath) if err != nil { log15.Crit("Failed to load private key", "error", err) return } res, err := http.Get("https://etherapis.appspot.com/faucet/fund?key=" + string(key)) if err != nil { log15.Crit("Failed to upload private key to faucet", "error", err) return } res.Body.Close() log15.Info("Account uploaded to faucet", "account", fmt.Sprintf("0x%x", account.Address)) os.Remove(keyPath) } // Just wait a bit to ensure transactions get propagated into the network log15.Info("Sleeping to ensure transaction propagation") time.Sleep(10 * time.Second) return case len(*queryFlag) > 0: // Check whether any of our accounts are subscribed to this particular service accounts, err := eth.AccountManager().Accounts() if err != nil || len(accounts) == 0 { log15.Crit("Failed to retrieve account", "accounts", len(accounts), "error", err) return } provider := common.HexToAddress(*queryFlag) log15.Info("Checking subscription status", "service", fmt.Sprintf("0x%x", provider)) for i, account := range accounts { // Check if a subscription exists if !contract.Exists(account.Address, provider) { fmt.Printf("Account #%d: [0x%x]: not subscribed.\n", i, account.Address) continue } // Retrieve the current balance on the subscription ethers := contract.Call("getChannelValue", contract.ChannelId(account.Address, provider)).(*big.Int) funds := float64(new(big.Int).Div(ethers, common.Finney).Int64()) / 1000 fmt.Printf("Account #%d: [0x%x]: subscribed, with %v ether(s) left.\n", i, account.Address, funds) } return case len(*subToFlag) > 0: // Subscription requested, make sure all the details are provided accounts, err := eth.AccountManager().Accounts() if err != nil || len(accounts) < *subAccFlag { log15.Crit("Failed to retrieve account", "accounts", len(accounts), "requested", *subAccFlag, "error", err) return } account := accounts[*subAccFlag] // Check if a subscription exists provider := common.HexToAddress(*subToFlag) if contract.Exists(account.Address, provider) { log15.Error("Account already subscribed", "index", *subAccFlag, "account", fmt.Sprintf("0x%x", account.Address), "service", fmt.Sprintf("0x%x", provider)) return } // Try to subscribe and wait until it completes keystore := client.Keystore() key, err := keystore.GetKey(account.Address, "") if err != nil { log15.Crit("Failed to unlock account", "account", fmt.Sprintf("0x%x", account.Address), "error", err) return } amount := new(big.Int).Mul(big.NewInt(int64(1000000000**subFundFlag)), common.Shannon) log15.Info("Subscribing to new payment channel", "account", fmt.Sprintf("0x%x", account.Address), "service", fmt.Sprintf("0x%x", provider), "ethers", *subFundFlag) pend := make(chan *channels.Channel) tx, err := contract.NewChannel(key.PrivateKey, provider, amount, big.NewInt(1), func(sub *channels.Channel) { pend <- sub }) if err != nil { log15.Crit("Failed to create subscription", "error", err) return } if err := eth.TxPool().Add(tx); err != nil { log15.Crit("Failed to execute subscription", "error", err) return } log15.Info("Waiting for subscription to be finalized...", "tx", tx) log15.Info("Successfully subscribed", "channel", fmt.Sprintf("%x", (<-pend).Id)) return } if *testFlag { accounts, err := eth.AccountManager().Accounts() if err != nil { log15.Crit("Failed retrieving accounts", "err", err) } if len(accounts) < 2 { log15.Crit("Test vectors requires at least 2 accounts", "len", len(accounts)) return } log15.Info("Attempting channel test vectors...") from := accounts[0].Address eth.AccountManager().Unlock(from, "") to := accounts[0].Address log15.Info("making channel name...", "from", from.Hex(), "to", to.Hex(), "ID", contract.ChannelId(from, to).Hex()) log15.Info("checking existence...", "exists", contract.Exists(from, to)) amount := big.NewInt(1) hash := contract.Call("getHash", from, to, 0, amount).([]byte) log15.Info("signing data", "to", to.Hex(), "amount", amount, "hash", common.ToHex(hash)) sig, err := eth.AccountManager().Sign(accounts[0], hash) if err != nil { log15.Crit("signing vailed", "err", err) return } log15.Info("verifying signature", "sig", common.ToHex(sig)) if contract.ValidateSig(from, to, 0, amount, sig) { log15.Info("signature was valid and was verified by the EVM") } else { log15.Crit("signature was invalid") return } log15.Info("verifying payment", "sig", common.ToHex(sig)) if valid, _ := contract.Verify(from, to, 0, amount, sig); valid { log15.Info("payment was valid and was verified by the EVM") } else { log15.Crit("payment was invalid") return } log15.Info("verifying invalid payment", "nonce", 1) if valid, _ := contract.Verify(from, to, 1, amount, sig); valid { log15.Crit("payment was valid") return } else { log15.Info("payment was invalid") } } // If we're running a proxy, start processing external requests if *proxyFlag != "" { // Subscription requested, make sure all the details are provided accounts, err := eth.AccountManager().Accounts() if err != nil || len(accounts) < *subAccFlag { log15.Crit("Failed to retrieve account", "accounts", len(accounts), "requested", *subAccFlag, "error", err) return } account := accounts[*subAccFlag] if err := eth.AccountManager().Unlock(account.Address, ""); err != nil { log15.Crit("Failed to unlock provider account", "account", fmt.Sprintf("0x%x", account.Address), "error", err) return } log15.Info("Setuping vault...", "owner", account.Address.Hex()) // Create the payment vault to hold the various authorizations vault := proxy.NewVault(NewCharger(account, eth.TxPool(), contract, eth.AccountManager())) vault.AutoCharge(*chargeFlag) for i, config := range strings.Split(*proxyFlag, ",") { // Split the proxy configuration parts := strings.Split(config, ":") if len(parts) != 3 { log15.Crit("Invalid proxy config", "config", config) return } extPort, err := strconv.Atoi(parts[0]) if err != nil || extPort < 0 || extPort > 65535 { log15.Crit("Invalid external port number", "port", parts[0]) return } intPort, err := strconv.Atoi(parts[1]) if err != nil || intPort < 0 || intPort > 65535 { log15.Crit("Invalid internal port number", "port", parts[1]) return } var kind proxy.ProxyType switch strings.ToLower(parts[2]) { case "call": kind = proxy.CallProxy case "data": kind = proxy.DataProxy default: log15.Crit("Unsupported proxy type", "type", parts[2], "allowed", []string{"call", "data"}) return } // Create and start the new proxy gateway := proxy.New(i, extPort, intPort, kind, contract, vault) go func() { if err := gateway.Start(); err != nil { log15.Crit("Failed to start proxy", "error", err) os.Exit(-1) } }() } // Wait indefinitely, for now at least for { time.Sleep(time.Second) } } // Clean up for now log15.Info("Terminating Ethereum client...") if err := client.Stop(); err != nil { log15.Crit("Failed to terminate Ethereum client", "error", err) return } }
// WriteGenesisBlock writes the genesis block to the database as block number 0 func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block, error) { contents, err := ioutil.ReadAll(reader) if err != nil { return nil, err } var genesis struct { Nonce string Timestamp string ParentHash string ExtraData string GasLimit string Difficulty string Mixhash string Coinbase string Alloc map[string]struct { Code string Storage map[string]string Balance string } } if err := json.Unmarshal(contents, &genesis); err != nil { return nil, err } // creating with empty hash always works statedb, _ := state.New(common.Hash{}, chainDb) for addr, account := range genesis.Alloc { address := common.HexToAddress(addr) statedb.AddBalance(address, common.String2Big(account.Balance)) statedb.SetCode(address, common.Hex2Bytes(account.Code)) for key, value := range account.Storage { statedb.SetState(address, common.HexToHash(key), common.HexToHash(value)) } } root, stateBatch := statedb.CommitBatch() difficulty := common.String2Big(genesis.Difficulty) block := types.NewBlock(&types.Header{ Nonce: types.EncodeNonce(common.String2Big(genesis.Nonce).Uint64()), Time: common.String2Big(genesis.Timestamp), ParentHash: common.HexToHash(genesis.ParentHash), Extra: common.FromHex(genesis.ExtraData), GasLimit: common.String2Big(genesis.GasLimit), Difficulty: difficulty, MixDigest: common.HexToHash(genesis.Mixhash), Coinbase: common.HexToAddress(genesis.Coinbase), Root: root, }, nil, nil, nil) if block := GetBlock(chainDb, block.Hash()); block != nil { glog.V(logger.Info).Infoln("Genesis block already in chain. Writing canonical number") err := WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) if err != nil { return nil, err } return block, nil } if err := stateBatch.Write(); err != nil { return nil, fmt.Errorf("cannot write state: %v", err) } if err := WriteTd(chainDb, block.Hash(), difficulty); err != nil { return nil, err } if err := WriteBlock(chainDb, block); err != nil { return nil, err } if err := WriteBlockReceipts(chainDb, block.Hash(), nil); err != nil { return nil, err } if err := WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()); err != nil { return nil, err } if err := WriteHeadBlockHash(chainDb, block.Hash()); err != nil { return nil, err } return block, nil }
// Transact forms a transaction from the given arguments and submits it to the // transactio pool for execution. func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { if len(toStr) > 0 && toStr != "0x" && !common.IsHexAddress(toStr) { return "", errors.New("invalid address") } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.Big(valueStr) gas *big.Int price *big.Int data []byte contractCreation bool ) if len(gasStr) == 0 { gas = big.NewInt(90000) } else { gas = common.Big(gasStr) } if len(gasPriceStr) == 0 { price = big.NewInt(10000000000000) } else { price = common.Big(gasPriceStr) } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } nonce := be.txPool.State().GetNonce(from) if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } var tx *types.Transaction if contractCreation { tx = types.NewContractCreation(nonce, value, gas, price, data) } else { tx = types.NewTransaction(nonce, to, value, gas, price, data) } acc := accounts.Account{from} signature, err := be.am.Sign(acc, tx.SigHash().Bytes()) if err != nil { return "", err } signedTx, err := tx.WithSignature(signature) if err != nil { return "", err } be.txPool.SetLocal(signedTx) if err := be.txPool.Add(signedTx); err != nil { return "", nil } if contractCreation { addr := crypto.CreateAddress(from, nonce) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) } else { glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) } return signedTx.Hash().Hex(), nil }
"strings" "sync" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/accounts/abi" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/common" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/core" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/core/types" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/core/vm" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/crypto" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/eth/filters" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/ethdb" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/event" ) // contractAddress is the static address on which the contract resides var contractAddress = common.HexToAddress("0x8e517c8f4cc7714ef4723d0b70205c53d264c142") // signFn is a signer function callback when the contract requires a method to // sign the transaction before submission. type signFn func(*types.Transaction) (*types.Transaction, error) // Channels is the channels contract reflecting that on the ethereum network. The // channels contract handles all validation and verifications of payments and // allows you to redeem cheques. // // Channels implements the proxy.Verifier and proxy.Charges interfaces. type Channels struct { abi abi.ABI blockchain *core.BlockChain filters *filters.FilterSystem
// 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 core import ( "math/big" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/common" "github.com/gophergala2016/etherapis/etherapis/Godeps/_workspace/src/github.com/ethereum/go-ethereum/core/state" ) var ( jeff = common.HexToAddress("959c33de5961820567930eccce51ea715c496f85") vitalik = common.HexToAddress("c8158da0b567a8cc898991c2c2a073af67dc03a9") christoph = common.HexToAddress("7a19a893f91d5b6e2cdf941b6acbba2cbcf431ee") gav = common.HexToAddress("539dd9aaf45c3feb03f9c004f4098bd3268fef6b") ) // Canary will check the 0'd address of the 4 contracts above. // If two or more are set to anything other than a 0 the canary // dies a horrible death. func Canary(statedb *state.StateDB) bool { var r int if (statedb.GetState(jeff, common.Hash{}).Big().Cmp(big.NewInt(0)) > 0) { r++ } if (statedb.GetState(gav, common.Hash{}).Big().Cmp(big.NewInt(0)) > 0) { r++