From 516e879d50939c19d3582c424d23a6438367c220 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Sun, 15 Mar 2020 22:51:25 +0530 Subject: [PATCH 1/7] add OBT --- repo/currency_definition.go | 2 + schema/configuration.go | 12 + schema/constants.go | 25 + .../OpenBazaar/go-ethwallet/wallet/client.go | 2 +- .../go-ethwallet/wallet/erc20_wallet.go | 1058 ++++++++++++++++- .../OpenBazaar/go-ethwallet/wallet/wallet.go | 7 +- .../OpenBazaar/multiwallet/multiwallet.go | 10 + .../OpenBazaar/wallet-interface/datastore.go | 10 + 8 files changed, 1070 insertions(+), 56 deletions(-) diff --git a/repo/currency_definition.go b/repo/currency_definition.go index a12b1d9b75..560830ae4e 100644 --- a/repo/currency_definition.go +++ b/repo/currency_definition.go @@ -72,6 +72,7 @@ var ( "LTC": {Name: "Litecoin", Code: CurrencyCode("LTC"), CurrencyType: Crypto, Divisibility: 8, BlockTime: 150 * time.Second}, "ZEC": {Name: "Zcash", Code: CurrencyCode("ZEC"), CurrencyType: Crypto, Divisibility: 8, BlockTime: DefaultBlockTime}, "ETH": {Name: "Ethereum", Code: CurrencyCode("ETH"), CurrencyType: Crypto, Divisibility: 18, BlockTime: 10 * time.Second}, + "OBT": {Name: "OB Token", Code: CurrencyCode("OBT"), CurrencyType: Crypto, Divisibility: 18, BlockTime: 10 * time.Second}, } testnetCryptoDefinitions = map[string]CurrencyDefinition{ "TBTC": {Name: "Testnet Bitcoin", Code: CurrencyCode("TBTC"), CurrencyType: Crypto, Divisibility: 8, BlockTime: DefaultBlockTime}, @@ -79,6 +80,7 @@ var ( "TLTC": {Name: "Testnet Litecoin", Code: CurrencyCode("TLTC"), CurrencyType: Crypto, Divisibility: 8, BlockTime: 150 * time.Second}, "TZEC": {Name: "Testnet Zcash", Code: CurrencyCode("TZEC"), CurrencyType: Crypto, Divisibility: 8, BlockTime: DefaultBlockTime}, "TETH": {Name: "Testnet Ethereum", Code: CurrencyCode("TETH"), CurrencyType: Crypto, Divisibility: 18, BlockTime: 10 * time.Second}, + "TOBT": {Name: "Testnet OB Token", Code: CurrencyCode("TOBT"), CurrencyType: Crypto, Divisibility: 18, BlockTime: 10 * time.Second}, } fiatDefinitions = map[string]CurrencyDefinition{ "AED": {Name: "UAE Dirham", Code: CurrencyCode("AED"), CurrencyType: Fiat, Divisibility: 2}, diff --git a/schema/configuration.go b/schema/configuration.go index 14955c7e63..bd98d76acb 100644 --- a/schema/configuration.go +++ b/schema/configuration.go @@ -36,6 +36,7 @@ type WalletsConfig struct { LTC *CoinConfig `json:"LTC"` ZEC *CoinConfig `json:"ZEC"` ETH *CoinConfig `json:"ETH"` + OBT *CoinConfig `json:"OBT"` } type CoinConfig struct { @@ -129,6 +130,17 @@ func DefaultWalletsConfig() *WalletsConfig { MaxFee: 200, WalletOptions: EthereumDefaultOptions(), }, + OBT: &CoinConfig{ + Type: WalletTypeAPI, + APIPool: CoinPoolOBT, + APITestnetPool: CoinPoolTOBT, + FeeAPI: "", // intentionally blank + LowFeeDefault: 7, + MediumFeeDefault: 15, + HighFeeDefault: 30, + MaxFee: 200, + WalletOptions: OBTDefaultOptions(), + }, } } diff --git a/schema/constants.go b/schema/constants.go index 0c09b7bec5..68a92e9af4 100644 --- a/schema/constants.go +++ b/schema/constants.go @@ -47,6 +47,14 @@ const ( EthereumRegistryAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" EthereumRegistryAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" + // OB Tokens + OBTRegistryAddressMainnet = "0x5c69ccf91eab4ef80d9929b3c1b4d5bc03eb0981" + OBTRegistryAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" + OBTRegistryAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" + OBTAddressMainnet = "0x5c69ccf91eab4ef80d9929b3c1b4d5bc03eb0981" + OBTAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" + OBTAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" + DataPushNodeOne = "QmbwN82MVyBukT7WTdaQDppaACo62oUfma8dUa5R9nBFHm" DataPushNodeTwo = "QmPPg2qeF3n2KvTRXRZLaTwHCw8JxzF4uZK93RfMoDvf2o" DataPushNodeThree = "QmY8puEnVx66uEet64gAf4VZRo7oUyMCwG6KdB9KM92EGQ" @@ -89,6 +97,19 @@ func EthereumDefaultOptions() map[string]interface{} { } } +func OBTDefaultOptions() map[string]interface{} { + return map[string]interface{}{ + "Name": "OB Token", + "Symbol": "OBT", + "MainNetAddress": OBTAddressMainnet, + "RinkebyAddress": OBTAddressRinkeby, + "RopstenAddress": OBTAddressRopsten, + "RegistryAddress": OBTRegistryAddressMainnet, + "RinkebyRegistryAddress": OBTRegistryAddressRinkeby, + "RopstenRegistryAddress": OBTRegistryAddressRopsten, + } +} + const ( WalletTypeAPI = "API" WalletTypeSPV = "SPV" @@ -100,12 +121,14 @@ const ( CoinAPIOpenBazaarLTC = "https://ltc.api.openbazaar.org/api" CoinAPIOpenBazaarZEC = "https://zec.api.openbazaar.org/api" CoinAPIOpenBazaarETH = "https://mainnet.infura.io" + CoinAPIOpenBazaarOBT = "https://mainnet.infura.io" CoinAPIOpenBazaarTBTC = "https://tbtc.api.openbazaar.org/api" CoinAPIOpenBazaarTBCH = "https://tbch.api.openbazaar.org/api" CoinAPIOpenBazaarTLTC = "https://tltc.api.openbazaar.org/api" CoinAPIOpenBazaarTZEC = "https://tzec.api.openbazaar.org/api" CoinAPIOpenBazaarTETH = "https://rinkeby.infura.io" + CoinAPIOpenBazaarTOBT = "https://rinkeby.infura.io" ) var ( @@ -114,10 +137,12 @@ var ( CoinPoolLTC = []string{CoinAPIOpenBazaarLTC} CoinPoolZEC = []string{CoinAPIOpenBazaarZEC} CoinPoolETH = []string{CoinAPIOpenBazaarETH} + CoinPoolOBT = []string{CoinAPIOpenBazaarOBT} CoinPoolTBTC = []string{CoinAPIOpenBazaarTBTC} CoinPoolTBCH = []string{CoinAPIOpenBazaarTBCH} CoinPoolTLTC = []string{CoinAPIOpenBazaarTLTC} CoinPoolTZEC = []string{CoinAPIOpenBazaarTZEC} CoinPoolTETH = []string{CoinAPIOpenBazaarTETH} + CoinPoolTOBT = []string{CoinAPIOpenBazaarTOBT} ) diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go index b237d8af49..e1d1d0210b 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go @@ -142,7 +142,7 @@ func (client *EthClient) Transfer(from *Account, destAccount common.Address, val } // TransferToken will transfer erc20 token from this user account to dest address -func (client *EthClient) TransferToken(from *Account, toAddress common.Address, tokenAddress common.Address, value *big.Int) (common.Hash, error) { +func (client *EthClient) TransferToken(from *Account, toAddress common.Address, tokenAddress common.Address, value *big.Int, spendAll bool, fee big.Int) (common.Hash, error) { var err error fromAddress := from.Address() nonce, err := client.PendingNonceAt(context.Background(), fromAddress) diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index a6aff85b06..39e7f1c8bd 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -5,12 +5,19 @@ import ( "context" "crypto/ecdsa" "encoding/binary" + "encoding/json" "errors" "fmt" + "io/ioutil" "math/big" + "net/http" + "sort" + "strconv" + "strings" "time" "github.com/OpenBazaar/multiwallet/config" + ut "github.com/OpenBazaar/openbazaar-go/util" wi "github.com/OpenBazaar/wallet-interface" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -24,11 +31,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/nanmu42/etherscan-api" "golang.org/x/net/proxy" "github.com/OpenBazaar/go-ethwallet/util" ) +var doneERC20, doneBalanceTickerERC20 chan bool +var currencyDefinitionERC20 wi.CurrencyDefinition + // ERC20Wallet is the wallet implementation for ethereum type ERC20Wallet struct { client *EthClient @@ -39,6 +50,7 @@ type ERC20Wallet struct { ppsct *Escrow db wi.Datastore exchangeRates wi.ExchangeRates + params *chaincfg.Params symbol string name string deployAddressMain common.Address @@ -51,7 +63,6 @@ type ERC20Wallet struct { // GenTokenScriptHash - used to generate script hash for erc20 token as per // escrow smart contract func GenTokenScriptHash(script EthRedeemScript) ([32]byte, string, error) { - //ahash := sha3.NewKeccak256() a := make([]byte, 4) binary.BigEndian.PutUint32(a, script.Timeout) arr := append(script.TxnID.Bytes(), append([]byte{script.Threshold}, @@ -59,11 +70,9 @@ func GenTokenScriptHash(script EthRedeemScript) ([32]byte, string, error) { append(script.Seller.Bytes(), append(script.Moderator.Bytes(), append(script.MultisigAddress.Bytes(), script.TokenAddress.Bytes()...)...)...)...)...)...)...) - //ahash.Write(arr) var retHash [32]byte - //copy(retHash[:], ahash.Sum(nil)[:]) - copy(retHash[:], crypto.Keccak256(arr)) + copy(retHash[:], crypto.Keccak256(arr)[:]) ahashStr := hexutil.Encode(retHash[:]) return retHash, ahashStr, nil @@ -86,7 +95,6 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str return nil, err } var myAccount *Account - myAccount, err = NewAccountFromMnemonic(mnemonic, "", params) if err != nil { log.Errorf("mnemonic based pk generation failed: %s", err.Error()) @@ -98,8 +106,14 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str var regAddr interface{} var ok bool - if regAddr, ok = cfg.Options["RegistryAddress"]; !ok { - log.Errorf("ethereum registry not found: %s", cfg.Options["RegistryAddress"]) + registryKey := "RegistryAddress" + if strings.Contains(cfg.ClientAPIs[0], "rinkeby") { + registryKey = "RinkebyRegistryAddress" + } else if strings.Contains(cfg.ClientAPIs[0], "ropsten") { + registryKey = "RopstenRegistryAddress" + } + if regAddr, ok = cfg.Options[registryKey]; !ok { + log.Errorf("ethereum registry not found: %s", cfg.Options[registryKey]) return nil, err } @@ -110,7 +124,6 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str log.Errorf("error initilaizing contract failed: %s", err.Error()) return nil, err } - er := NewEthereumPriceFetcher(proxy) token := TokenDetail{} @@ -151,6 +164,11 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str return nil, err } + currencyDefinitionERC20 = wi.CurrencyDefinition{ + Code: token.symbol, + Divisibility: 18, + } + return &ERC20Wallet{ client: client, account: myAccount, @@ -160,6 +178,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str ppsct: nil, db: cfg.DB, exchangeRates: er, + params: params, symbol: token.symbol, name: token.name, deployAddressMain: token.deployAddressMain, @@ -172,7 +191,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str // Params - return nil to comply func (wallet *ERC20Wallet) Params() *chaincfg.Params { - return nil + return wallet.params } // GetBalance returns the balance for the wallet @@ -186,25 +205,133 @@ func (wallet *ERC20Wallet) GetUnconfirmedBalance() (*big.Int, error) { } // Transfer will transfer the amount from this wallet to the spec address -func (wallet *ERC20Wallet) Transfer(to string, value *big.Int) (common.Hash, error) { +func (wallet *ERC20Wallet) Transfer(to string, value *big.Int, spendAll bool, fee big.Int) (common.Hash, error) { toAddress := common.HexToAddress(to) - //wallet.token.Transfer() - return wallet.client.TransferToken(wallet.account, toAddress, wallet.deployAddressMain, value) + return wallet.client.TransferToken(wallet.account, toAddress, wallet.deployAddressMain, value, spendAll, fee) } // Start will start the wallet daemon func (wallet *ERC20Wallet) Start() { - // daemonize the wallet + doneERC20 = make(chan bool) + doneBalanceTickerERC20 = make(chan bool) + // start the ticker to check for pending txn rcpts + go func(wallet *ERC20Wallet) { + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + for { + select { + case <-done: + return + case <-ticker.C: + // get the pending txns + txns, err := wallet.db.Txns().GetAll(true) + if err != nil { + continue + } + for _, txn := range txns { + hash := common.HexToHash(txn.Txid) + go func(txnData []byte) { + _, err := wallet.checkTxnRcpt(&hash, txnData) + if err != nil { + log.Errorf(err.Error()) + } + }(txn.Bytes) + } + } + } + }(wallet) + + // start the ticker to check for balance + go func(wallet *ERC20Wallet) { + ticker := time.NewTicker(15 * time.Second) + defer ticker.Stop() + + currentBalance, err := wallet.GetBalance() + if err != nil { + log.Infof("err fetching initial balance: %v", err) + } + currentTip, _ := wallet.ChainTip() + + for { + select { + case <-doneBalanceTickerERC20: + return + case <-ticker.C: + // fetch the current balance + fetchedBalance, err := wallet.GetBalance() + if err != nil { + log.Infof("err fetching balance at %v: %v", time.Now(), err) + continue + } + if fetchedBalance.Cmp(currentBalance) != 0 { + // process balance change + go wallet.processBalanceChange(currentBalance, fetchedBalance, currentTip) + currentTip, _ = wallet.ChainTip() + currentBalance = fetchedBalance + } + } + } + }(wallet) +} + +func (wallet *ERC20Wallet) processBalanceChange(previousBalance, currentBalance *big.Int, currentHead uint32) { + count := 0 + cTip := int(currentHead) + value := new(big.Int).Sub(currentBalance, previousBalance) + for count < 30 { + txns, err := wallet.TransactionsFromBlock(&cTip) + if err == nil && len(txns) > 0 { + count = 30 + txncb := wi.TransactionCallback{ + Txid: util.EnsureCorrectPrefix(txns[0].Txid), + Outputs: []wi.TransactionOutput{}, + Inputs: []wi.TransactionInput{}, + Height: txns[0].Height, + Timestamp: time.Now(), + Value: *value, + WatchOnly: false, + } + for _, l := range wallet.listeners { + go l(txncb) + } + continue + } + + time.Sleep(2 * time.Second) + count++ + } +} + +func (wallet *ERC20Wallet) invokeTxnCB(txnID string, value *big.Int) { + txncb := wi.TransactionCallback{ + Txid: util.EnsureCorrectPrefix(txnID), + Outputs: []wi.TransactionOutput{}, + Inputs: []wi.TransactionInput{}, + Height: 0, + Timestamp: time.Now(), + Value: *value, + WatchOnly: false, + } + for _, l := range wallet.listeners { + go l(txncb) + } } // CurrencyCode returns symbol func (wallet *ERC20Wallet) CurrencyCode() string { - return wallet.symbol + if wallet.params == nil { + return wallet.symbol + } + if wallet.params.Name == chaincfg.MainNetParams.Name { + return wallet.symbol + } + return "T" + wallet.symbol } // IsDust Check if this amount is considered dust - 10000 wei -func (wallet *ERC20Wallet) IsDust(amount int64) bool { - return amount < 10000 +func (wallet *ERC20Wallet) IsDust(amount big.Int) bool { + return amount.Cmp(big.NewInt(10000)) <= 0 } // MasterPrivateKey - Get the master private key @@ -265,6 +392,30 @@ func (wallet *ERC20Wallet) HasKey(addr btcutil.Address) bool { } // Balance - Get the confirmed and unconfirmed balances +func (wallet *ERC20Wallet) Balance() (confirmed, unconfirmed wi.CurrencyValue) { + var balance, ucbalance wi.CurrencyValue + bal, err := wallet.GetBalance() + if err == nil { + balance = wi.CurrencyValue{ + Value: *bal, + Currency: currencyDefinitionERC20, + } + } + ucbal, err := wallet.GetUnconfirmedBalance() + ucb := big.NewInt(0) + if err == nil { + if ucbal.Cmp(bal) > 0 { + ucb.Sub(ucbal, bal) + } + } + ucbalance = wi.CurrencyValue{ + Value: *ucb, + Currency: EthCurrencyDefinition, + } + return balance, ucbalance +} + +/* func (wallet *ERC20Wallet) Balance() (confirmed, unconfirmed int64) { var balance, ucbalance int64 bal, err := wallet.GetBalance() @@ -281,8 +432,50 @@ func (wallet *ERC20Wallet) Balance() (confirmed, unconfirmed int64) { } return balance, ucb } +*/ + +// Transactions - Returns a list of transactions for this wallet +// TransactionsFromBlock - Returns a list of transactions for this wallet begining from the specified block +func (wallet *ERC20Wallet) TransactionsFromBlock(startBlock *int) ([]wi.Txn, error) { + txns, err := wallet.client.eClient.NormalTxByAddress(util.EnsureCorrectPrefix(wallet.account.Address().String()), startBlock, nil, + 1, 0, false) + if err != nil { + log.Error("err fetching transactions : ", err) + return []wi.Txn{}, nil + } + + ret := []wi.Txn{} + for _, t := range txns { + status := wi.StatusConfirmed + prefix := "" + if t.IsError != 0 { + status = wi.StatusError + } + if strings.ToLower(t.From) == strings.ToLower(wallet.address.String()) { + prefix = "-" + } + tnew := wi.Txn{ + Txid: util.EnsureCorrectPrefix(t.Hash), + Value: prefix + t.Value.Int().String(), + Height: int32(t.BlockNumber), + Timestamp: t.TimeStamp.Time(), + WatchOnly: false, + Confirmations: int64(t.Confirmations), + Status: wi.StatusCode(status), + Bytes: []byte(t.Input), + } + ret = append(ret, tnew) + } + + return ret, nil +} // Transactions - Returns a list of transactions for this wallet +func (wallet *ERC20Wallet) Transactions() ([]wi.Txn, error) { + return wallet.TransactionsFromBlock(nil) +} + +/* func (wallet *ERC20Wallet) Transactions() ([]wi.Txn, error) { txns, err := wallet.client.eClient.NormalTxByAddress(wallet.account.Address().String(), nil, nil, 1, 0, true) @@ -311,6 +504,7 @@ func (wallet *ERC20Wallet) Transactions() ([]wi.Txn, error) { return ret, nil } +*/ // GetTransaction - Get info on a specific transaction func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { @@ -340,11 +534,113 @@ func (wallet *ERC20Wallet) ChainTip() (uint32, chainhash.Hash) { } // GetFeePerByte - Get the current fee per byte -func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) uint64 { - return 0 +func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { + est, err := wallet.client.GetEthGasStationEstimate() + ret := big.NewInt(0) + if err != nil { + log.Errorf("err fetching ethgas station data: %v", err) + return *ret + } + switch feeLevel { + case wi.NORMAL: + ret, _ = big.NewFloat(est.Average * 100000000).Int(nil) + case wi.ECONOMIC: + ret, _ = big.NewFloat(est.SafeLow * 100000000).Int(nil) + case wi.PRIOIRTY, wi.FEE_BUMP: + ret, _ = big.NewFloat(est.Fast * 100000000).Int(nil) + } + return *ret } // Spend - Send ether to an external wallet +func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string, spendAll bool) (*chainhash.Hash, error) { + var hash common.Hash + var h *chainhash.Hash + var err error + actualRecipient := addr + + if referenceID == "" { + // no referenceID means this is a direct transfer + hash, err = wallet.Transfer(util.EnsureCorrectPrefix(addr.String()), &amount, spendAll, wallet.GetFeePerByte(feeLevel)) + } else { + // this is a spend which means it has to be linked to an order + // specified using the referenceID + + // check if the addr is a multisig addr + scripts, err := wallet.db.WatchedScripts().GetAll() + if err != nil { + return nil, err + } + isScript := false + addrEth := common.HexToAddress(addr.String()) + key := addrEth.Bytes() + redeemScript := []byte{} + + for _, script := range scripts { + if bytes.Equal(key, script[:common.AddressLength]) { + isScript = true + redeemScript = script[common.AddressLength:] + break + } + } + + if isScript { + ethScript, err := DeserializeEthScript(redeemScript) + if err != nil { + return nil, err + } + _, scrHash, err := GenScriptHash(ethScript) + if err != nil { + log.Error(err.Error()) + } + addrScrHash := common.HexToAddress(scrHash) + actualRecipient = EthAddress{address: &addrScrHash} + hash, _, err = wallet.callAddTransaction(ethScript, &amount, feeLevel) + if err != nil { + log.Errorf("error call add txn: %v", err) + return nil, wi.ErrInsufficientFunds + } + } else { + if !wallet.balanceCheck(feeLevel, amount) { + return nil, wi.ErrInsufficientFunds + } + hash, err = wallet.Transfer(util.EnsureCorrectPrefix(addr.String()), &amount, spendAll, wallet.GetFeePerByte(feeLevel)) + } + if err != nil { + return nil, err + } + + // txn is pending + nonce, err := wallet.client.GetTxnNonce(util.EnsureCorrectPrefix(hash.Hex())) + if err == nil { + data, err := SerializePendingTxn(PendingTxn{ + TxnID: hash, + Amount: amount.String(), + OrderID: referenceID, + Nonce: nonce, + From: wallet.address.EncodeAddress(), + To: actualRecipient.EncodeAddress(), + WithInput: false, + }) + if err == nil { + err0 := wallet.db.Txns().Put(data, ut.NormalizeAddress(hash.Hex()), "0", 0, time.Now(), true) + if err0 != nil { + log.Error(err0.Error()) + } + } + } + } + + if err == nil { + h, err = util.CreateChainHash(hash.Hex()) + if err == nil { + wallet.invokeTxnCB(h.String(), &amount) + } + } + return h, err +} + +/* func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string) (*chainhash.Hash, error) { var hash common.Hash var h *chainhash.Hash @@ -412,7 +708,9 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel } return h, err } +*/ +/* func (wallet *ERC20Wallet) createTxnCallback(txID, orderID string, toAddress btcutil.Address, value big.Int, bTime time.Time) wi.TransactionCallback { output := wi.TransactionOutput{ Address: toAddress, @@ -440,6 +738,40 @@ func (wallet *ERC20Wallet) createTxnCallback(txID, orderID string, toAddress btc BlockTime: bTime, } } +*/ + +func (wallet *ERC20Wallet) createTxnCallback(txID, orderID string, toAddress btcutil.Address, value big.Int, bTime time.Time, withInput bool) wi.TransactionCallback { + output := wi.TransactionOutput{ + Address: toAddress, + Value: value, + Index: 1, + OrderID: orderID, + } + + input := wi.TransactionInput{} + + if withInput { + input = wi.TransactionInput{ + OutpointHash: []byte(util.EnsureCorrectPrefix(txID)), + OutpointIndex: 1, + LinkedAddress: toAddress, + Value: value, + OrderID: orderID, + } + + } + + return wi.TransactionCallback{ + Txid: util.EnsureCorrectPrefix(txID), + Outputs: []wi.TransactionOutput{output}, + Inputs: []wi.TransactionInput{input}, + Height: 1, + Timestamp: time.Now(), + Value: value, + WatchOnly: false, + BlockTime: bTime, + } +} func (wallet *ERC20Wallet) callListeners(txnCB wi.TransactionCallback) { for _, l := range wallet.listeners { @@ -447,29 +779,102 @@ func (wallet *ERC20Wallet) callListeners(txnCB wi.TransactionCallback) { } } +func (wallet *ERC20Wallet) AssociateTransactionWithOrder(txnCB wi.TransactionCallback) { + for _, l := range wallet.listeners { + go l(txnCB) + } +} + +// checkTxnRcpt check the txn rcpt status +func (wallet *ERC20Wallet) checkTxnRcpt(hash *common.Hash, data []byte) (*common.Hash, error) { + var rcpt *types.Receipt + pTxn, err := DeserializePendingTxn(data) + if err != nil { + return nil, err + } + + rcpt, err = wallet.client.TransactionReceipt(context.Background(), *hash) + if err != nil { + log.Infof("fetching txn rcpt: %v", err) + } + + if rcpt != nil { + // good. so the txn has been processed but we have to account for failed + // but valid txn like some contract condition causing revert + if rcpt.Status > 0 { + // all good to update order state + chash, err := util.CreateChainHash((*hash).Hex()) + if err != nil { + return nil, err + } + err = wallet.db.Txns().Delete(chash) + if err != nil { + log.Errorf("err deleting the pending txn : %v", err) + } + n := new(big.Int) + n, _ = n.SetString(pTxn.Amount, 10) + toAddr := common.HexToAddress(pTxn.To) + withInput := true + if pTxn.Amount != "0" { + toAddr = common.HexToAddress(util.EnsureCorrectPrefix(pTxn.To)) + withInput = pTxn.WithInput + } + go wallet.AssociateTransactionWithOrder( + wallet.createTxnCallback(util.EnsureCorrectPrefix(hash.Hex()), pTxn.OrderID, EthAddress{&toAddr}, + *n, time.Now(), withInput)) + } + } + return hash, nil + +} + // BumpFee - Bump the fee for the given transaction func (wallet *ERC20Wallet) BumpFee(txid chainhash.Hash) (*chainhash.Hash, error) { return chainhash.NewHashFromStr(txid.String()) } // EstimateFee - Calculates the estimated size of the transaction and returns the total fee for the given feePerByte -func (wallet *ERC20Wallet) EstimateFee(ins []wi.TransactionInput, outs []wi.TransactionOutput, feePerByte uint64) uint64 { +func (wallet *ERC20Wallet) EstimateFee(ins []wi.TransactionInput, outs []wi.TransactionOutput, feePerByte big.Int) big.Int { sum := big.NewInt(0) for _, out := range outs { gas, err := wallet.client.EstimateTxnGas(wallet.account.Address(), common.HexToAddress(out.Address.String()), &out.Value) if err != nil { - return sum.Uint64() + return *sum } sum.Add(sum, gas) } - return sum.Uint64() + return *sum } // EstimateSpendFee - Build a spend transaction for the amount and return the transaction fee -func (wallet *ERC20Wallet) EstimateSpendFee(amount int64, feeLevel wi.FeeLevel) (uint64, error) { - gas, err := wallet.client.EstimateGasSpend(wallet.account.Address(), big.NewInt(amount)) - return gas.Uint64(), err +func (wallet *ERC20Wallet) EstimateSpendFee(amount big.Int, feeLevel wi.FeeLevel) (big.Int, error) { + if !wallet.balanceCheck(feeLevel, amount) { + return *big.NewInt(0), wi.ErrInsufficientFunds + } + gas, err := wallet.client.EstimateGasSpend(wallet.account.Address(), &amount) + return *gas, err +} + +func (wallet *ERC20Wallet) balanceCheck(feeLevel wi.FeeLevel, amount big.Int) bool { + fee := wallet.GetFeePerByte(feeLevel) + if fee.Int64() == 0 { + return false + } + // lets check if the caller has enough balance to make the + // multisign call + requiredBalance := new(big.Int).Mul(&fee, big.NewInt(maxGasLimit)) + requiredBalance = new(big.Int).Add(requiredBalance, &amount) + currentBalance, err := wallet.GetBalance() + if err != nil { + log.Error("err fetching erc20 wallet balance") + currentBalance = big.NewInt(0) + } + if requiredBalance.Cmp(currentBalance) > 0 { + // the wallet does not have the required balance + return false + } + return true } // SweepAddress - Build and broadcast a transaction that sweeps all coins from an address. If it is a p2sh multisig, the redeemScript must be included @@ -594,6 +999,69 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value } +func (wallet *ERC20Wallet) callAddTransaction(script EthRedeemScript, value *big.Int, feeLevel wi.FeeLevel) (common.Hash, uint64, error) { + + h := common.BigToHash(big.NewInt(0)) + + // call registry to get the deployed address for the escrow ct + fromAddress := wallet.account.Address() + nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) + if err != nil { + log.Fatal(err) + } + gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) + if err != nil { + log.Fatal(err) + } + gasPriceETHGAS := wallet.GetFeePerByte(feeLevel) + if gasPriceETHGAS.Int64() < gasPrice.Int64() { + gasPriceETHGAS = *gasPrice + } + auth := bind.NewKeyedTransactor(wallet.account.privateKey) + + auth.Nonce = big.NewInt(int64(nonce)) + auth.Value = value // in wei + auth.GasLimit = maxGasLimit // in units + auth.GasPrice = gasPrice + + // lets check if the caller has enough balance to make the + // multisign call + if !wallet.balanceCheck(feeLevel, *big.NewInt(0)) { + // the wallet does not have the required balance + return h, nonce, wi.ErrInsufficientFunds + } + + shash, _, err := GenScriptHash(script) + if err != nil { + return h, nonce, err + } + + smtct, err := NewEscrow(script.MultisigAddress, wallet.client) + if err != nil { + log.Fatalf("error initilaizing contract failed: %s", err.Error()) + } + + var tx *types.Transaction + tx, err = smtct.AddTransaction(auth, script.Buyer, script.Seller, + script.Moderator, script.Threshold, script.Timeout, shash, script.TxnID) + if err == nil { + h = tx.Hash() + } else { + return h, 0, err + } + + txns = append(txns, wi.Txn{ + Txid: tx.Hash().Hex(), + Value: value.String(), + Height: int32(nonce), + Timestamp: time.Now(), + WatchOnly: false, + Bytes: tx.Data()}) + + return h, nonce, err + +} + // GenerateMultisigScript - Generate a multisig script from public keys. If a timeout is included the returned script should be a timelocked escrow which releases using the timeoutKey. func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, threshold int, timeout time.Duration, timeoutKey *hd.ExtendedKey) (btcutil.Address, []byte, error) { if uint32(timeout.Hours()) > 0 && timeoutKey == nil { @@ -618,7 +1086,8 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho if err != nil { return nil, nil, err } - ecKeys = append(ecKeys, common.BytesToAddress(ecKey.SerializeUncompressed())) + ePubkey := ecKey.ToECDSA() + ecKeys = append(ecKeys, crypto.PubkeyToAddress(*ePubkey)) } ver, err := wallet.registry.GetRecommendedVersion(nil, "escrow") @@ -638,7 +1107,6 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho builder.Buyer = ecKeys[0] builder.Seller = ecKeys[1] builder.MultisigAddress = ver.Implementation - builder.TokenAddress = wallet.deployAddressMain if threshold > 1 { builder.Moderator = ecKeys[2] @@ -663,59 +1131,120 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho return nil, nil, err } - //hash := sha3.NewKeccak256() - //hash.Write(redeemScript) - addr := common.HexToAddress(hexutil.Encode(crypto.Keccak256(redeemScript))) + addr := common.HexToAddress(hexutil.Encode(crypto.Keccak256(redeemScript))) //hash.Sum(nil)[:])) retAddr := EthAddress{&addr} scriptKey := append(addr.Bytes(), redeemScript...) - wallet.db.WatchedScripts().Put(scriptKey) + err = wallet.db.WatchedScripts().Put(scriptKey) + if err != nil { + log.Errorf("err saving the redeemscript: %v", err) + } return retAddr, redeemScript, nil } // CreateMultisigSignature - Create a signature for a multisig transaction -func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, outs []wi.TransactionOutput, key *hd.ExtendedKey, redeemScript []byte, feePerByte uint64) ([]wi.Signature, error) { +func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, outs []wi.TransactionOutput, key *hd.ExtendedKey, redeemScript []byte, feePerByte big.Int) ([]wi.Signature, error) { + + payouts := []wi.TransactionOutput{} + difference := new(big.Int) + + if len(ins) > 0 { + totalVal := ins[0].Value + outVal := new(big.Int) + for _, out := range outs { + outVal = new(big.Int).Add(outVal, &out.Value) + } + if totalVal.Cmp(outVal) != 0 { + if totalVal.Cmp(outVal) < 0 { + return nil, errors.New("payout greater than initial amount") + } + difference = new(big.Int).Sub(&totalVal, outVal) + } + } + + rScript, err := DeserializeEthScript(redeemScript) + if err != nil { + return nil, err + } + + indx := []int{} + mbvAddresses := make([]string, 3) + + for i, out := range outs { + if out.Value.Cmp(new(big.Int)) > 0 { + indx = append(indx, i) + } + if out.Address.String() == rScript.Moderator.Hex() { + mbvAddresses[0] = out.Address.String() + } else if out.Address.String() == rScript.Buyer.Hex() && (out.Value.Cmp(new(big.Int)) > 0) { + mbvAddresses[1] = out.Address.String() + } else { + mbvAddresses[2] = out.Address.String() + } + p := wi.TransactionOutput{ + Address: out.Address, + Value: out.Value, + Index: out.Index, + OrderID: out.OrderID, + } + payouts = append(payouts, p) + } + + if len(indx) > 0 { + diff := new(big.Int) + delta := new(big.Int) + diff.DivMod(difference, big.NewInt(int64(len(indx))), delta) + for _, i := range indx { + payouts[i].Value.Add(&payouts[i].Value, diff) + } + payouts[indx[0]].Value.Add(&payouts[indx[0]].Value, delta) + } + + sort.Slice(payouts, func(i, j int) bool { + return strings.Compare(payouts[i].Address.String(), payouts[j].Address.String()) == -1 + }) var sigs []wi.Signature - payables := make(map[string]*big.Int) - for _, out := range outs { + payables := make(map[string]big.Int) + addresses := []string{} + for _, out := range payouts { if out.Value.Cmp(big.NewInt(0)) <= 0 { continue } - val := &out.Value + val := new(big.Int).SetBytes(out.Value.Bytes()) // &out.Value if p, ok := payables[out.Address.String()]; ok { - sum := big.NewInt(0) - sum.Add(val, p) - payables[out.Address.String()] = sum + sum := new(big.Int).Add(val, &p) + payables[out.Address.String()] = *sum } else { - payables[out.Address.String()] = val + payables[out.Address.String()] = *val + addresses = append(addresses, out.Address.String()) } } + sort.Strings(addresses) destArr := []byte{} amountArr := []byte{} - for k, v := range payables { + for _, k := range mbvAddresses { + v := payables[k] + if v.Cmp(big.NewInt(0)) != 1 { + continue + } addr := common.HexToAddress(k) sample := [32]byte{} sampleDest := [32]byte{} copy(sampleDest[12:], addr.Bytes()) - a := make([]byte, 8) - binary.BigEndian.PutUint64(a, v.Uint64()) + val := v.Bytes() + l := len(val) - copy(sample[24:], a) + copy(sample[32-l:], val) destArr = append(destArr, sampleDest[:]...) amountArr = append(amountArr, sample[:]...) } - rScript, err := DeserializeEthScript(redeemScript) - if err != nil { - return nil, err - } - - shash, _, err := GenTokenScriptHash(rScript) + shash, _, err := GenScriptHash(rScript) if err != nil { return nil, err } @@ -756,6 +1285,8 @@ func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, ou txData = append(txData, []byte("Ethereum Signed Message:\n32")...) txData = append(txData, payloadHash[:]...) txnHash := crypto.Keccak256(txData) + log.Debugf("txnHash : %s", hexutil.Encode(txnHash)) + log.Debugf("phash : %s", hexutil.Encode(payloadHash[:])) copy(txHash[:], txnHash) sig, err := crypto.Sign(txHash[:], wallet.account.privateKey) @@ -767,6 +1298,380 @@ func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, ou return sigs, err } +// Multisign - Combine signatures and optionally broadcast +func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.TransactionOutput, sigs1 []wi.Signature, sigs2 []wi.Signature, redeemScript []byte, feePerByte big.Int, broadcast bool) ([]byte, error) { + + payouts := []wi.TransactionOutput{} + difference := new(big.Int) + + if len(ins) > 0 { + totalVal := &ins[0].Value + outVal := new(big.Int) + for _, out := range outs { + outVal.Add(outVal, &out.Value) + } + if totalVal.Cmp(outVal) != 0 { + if totalVal.Cmp(outVal) < 0 { + return nil, errors.New("payout greater than initial amount") + } + difference.Sub(totalVal, outVal) + } + } + + rScript, err := DeserializeEthScript(redeemScript) + if err != nil { + return nil, err + } + + indx := []int{} + referenceID := "" + mbvAddresses := make([]string, 3) + + for i, out := range outs { + if out.Value.Cmp(new(big.Int)) > 0 { + indx = append(indx, i) + } + if out.Address.String() == rScript.Moderator.Hex() { + indx = append(indx, i) + mbvAddresses[0] = out.Address.String() + } else if out.Address.String() == rScript.Buyer.Hex() { + mbvAddresses[1] = out.Address.String() + } else { + mbvAddresses[2] = out.Address.String() + } + p := wi.TransactionOutput{ + Address: out.Address, + Value: out.Value, + Index: out.Index, + OrderID: out.OrderID, + } + referenceID = out.OrderID + payouts = append(payouts, p) + } + + if len(indx) > 0 { + diff := new(big.Int) + delta := new(big.Int) + diff.DivMod(difference, big.NewInt(int64(len(indx))), delta) + for _, i := range indx { + payouts[i].Value.Add(&payouts[i].Value, diff) + } + payouts[indx[0]].Value.Add(&payouts[indx[0]].Value, delta) + } + + sort.Slice(payouts, func(i, j int) bool { + return strings.Compare(payouts[i].Address.String(), payouts[j].Address.String()) == -1 + }) + + payables := make(map[string]big.Int) + for _, out := range payouts { + if out.Value.Cmp(big.NewInt(0)) <= 0 { + continue + } + val := new(big.Int).SetBytes(out.Value.Bytes()) // &out.Value + if p, ok := payables[out.Address.String()]; ok { + sum := new(big.Int).Add(val, &p) + payables[out.Address.String()] = *sum + } else { + payables[out.Address.String()] = *val + } + } + + rSlice := [][32]byte{} + sSlice := [][32]byte{} + vSlice := []uint8{} + + var r [32]byte + var s [32]byte + var v uint8 + + if len(sigs1) > 0 && len(sigs1[0].Signature) > 0 { + r, s, v = util.SigRSV(sigs1[0].Signature) + rSlice = append(rSlice, r) + sSlice = append(sSlice, s) + vSlice = append(vSlice, v) + } + + if len(sigs2) > 0 && len(sigs2[0].Signature) > 0 { + r, s, v = util.SigRSV(sigs2[0].Signature) + rSlice = append(rSlice, r) + sSlice = append(sSlice, s) + vSlice = append(vSlice, v) + } + + shash, _, err := GenScriptHash(rScript) + if err != nil { + return nil, err + } + + smtct, err := NewEscrow(rScript.MultisigAddress, wallet.client) + if err != nil { + log.Fatalf("error initializing contract failed: %s", err.Error()) + } + + destinations := []common.Address{} + amounts := []*big.Int{} + + for _, k := range mbvAddresses { + v := payables[k] + if v.Cmp(big.NewInt(0)) == 1 { + destinations = append(destinations, common.HexToAddress(k)) + amounts = append(amounts, new(big.Int).SetBytes(v.Bytes())) + } + } + + fromAddress := wallet.account.Address() + nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) + if err != nil { + log.Fatal(err) + } + gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) + if err != nil { + log.Fatal(err) + } + auth := bind.NewKeyedTransactor(wallet.account.privateKey) + + auth.Nonce = big.NewInt(int64(nonce)) + auth.Value = big.NewInt(0) // in wei + auth.GasLimit = maxGasLimit // in units + auth.GasPrice = gasPrice + + // lets check if the caller has enough balance to make the + // multisign call + requiredBalance := new(big.Int).Mul(gasPrice, big.NewInt(maxGasLimit)) + currentBalance, err := wallet.GetBalance() + if err != nil { + log.Error("err fetching eth wallet balance") + currentBalance = big.NewInt(0) + } + + if requiredBalance.Cmp(currentBalance) > 0 { + // the wallet does not have the required balance + return nil, wi.ErrInsufficientFunds + } + + tx, txnErr := smtct.Execute(auth, vSlice, rSlice, sSlice, shash, destinations, amounts) + + if txnErr != nil { + return nil, txnErr + } + + txns = append(txns, wi.Txn{ + Txid: tx.Hash().Hex(), + Value: "0", + Height: int32(nonce), + Timestamp: time.Now(), + WatchOnly: false, + Bytes: tx.Data()}) + + // this is a pending txn + _, scrHash, err := GenScriptHash(rScript) + if err != nil { + log.Error(err.Error()) + } + data, err := SerializePendingTxn(PendingTxn{ + TxnID: tx.Hash(), + Amount: "0", + OrderID: referenceID, + Nonce: int32(nonce), + From: wallet.address.EncodeAddress(), + To: scrHash, + }) + if err == nil { + err0 := wallet.db.Txns().Put(data, ut.NormalizeAddress(tx.Hash().Hex()), "0", 0, time.Now(), true) + if err0 != nil { + log.Error(err0.Error()) + } + } + + return tx.Hash().Bytes(), nil +} + +// AddWatchedAddresses - Add a script to the wallet and get notifications back when coins are received or spent from it +func (wallet *ERC20Wallet) AddWatchedAddresses(addrs ...btcutil.Address) error { + // the reason eth wallet cannot use this as of now is because only the address + // is insufficient, the redeemScript is also required + return nil +} + +/* +// GenerateMultisigScript - Generate a multisig script from public keys. If a timeout is included the returned script should be a timelocked escrow which releases using the timeoutKey. +func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, threshold int, timeout time.Duration, timeoutKey *hd.ExtendedKey) (btcutil.Address, []byte, error) { + if uint32(timeout.Hours()) > 0 && timeoutKey == nil { + return nil, nil, errors.New("timeout key must be non nil when using an escrow timeout") + } + + if len(keys) < threshold { + return nil, nil, fmt.Errorf("unable to generate multisig script with "+ + "%d required signatures when there are only %d public "+ + "keys available", threshold, len(keys)) + } + + if len(keys) < 2 { + return nil, nil, fmt.Errorf("unable to generate multisig script with "+ + "%d required signatures when there are only %d public "+ + "keys available", threshold, len(keys)) + } + + var ecKeys []common.Address + for _, key := range keys { + ecKey, err := key.ECPubKey() + if err != nil { + return nil, nil, err + } + ecKeys = append(ecKeys, common.BytesToAddress(ecKey.SerializeUncompressed())) + } + + ver, err := wallet.registry.GetRecommendedVersion(nil, "escrow") + if err != nil { + log.Fatal(err) + } + + if util.IsZeroAddress(ver.Implementation) { + return nil, nil, errors.New("no escrow contract available") + } + + builder := EthRedeemScript{} + + builder.TxnID = common.BytesToAddress(util.ExtractChaincode(&keys[0])) + builder.Timeout = uint32(timeout.Hours()) + builder.Threshold = uint8(threshold) + builder.Buyer = ecKeys[0] + builder.Seller = ecKeys[1] + builder.MultisigAddress = ver.Implementation + builder.TokenAddress = wallet.deployAddressMain + + if threshold > 1 { + builder.Moderator = ecKeys[2] + } + switch threshold { + case 1: + { + // Seller is offline + } + case 2: + { + // Moderated payment + } + default: + { + // handle this + } + } + + redeemScript, err := SerializeEthScript(builder) + if err != nil { + return nil, nil, err + } + + //hash := sha3.NewKeccak256() + //hash.Write(redeemScript) + addr := common.HexToAddress(hexutil.Encode(crypto.Keccak256(redeemScript))) + retAddr := EthAddress{&addr} + + scriptKey := append(addr.Bytes(), redeemScript...) + wallet.db.WatchedScripts().Put(scriptKey) + + return retAddr, redeemScript, nil +} +*/ + +/* +// CreateMultisigSignature - Create a signature for a multisig transaction +func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, outs []wi.TransactionOutput, key *hd.ExtendedKey, redeemScript []byte, feePerByte uint64) ([]wi.Signature, error) { + + var sigs []wi.Signature + + payables := make(map[string]*big.Int) + for _, out := range outs { + if out.Value.Cmp(big.NewInt(0)) <= 0 { + continue + } + val := &out.Value + if p, ok := payables[out.Address.String()]; ok { + sum := big.NewInt(0) + sum.Add(val, p) + payables[out.Address.String()] = sum + } else { + payables[out.Address.String()] = val + } + } + + destArr := []byte{} + amountArr := []byte{} + + for k, v := range payables { + addr := common.HexToAddress(k) + sample := [32]byte{} + sampleDest := [32]byte{} + copy(sampleDest[12:], addr.Bytes()) + a := make([]byte, 8) + binary.BigEndian.PutUint64(a, v.Uint64()) + + copy(sample[24:], a) + destArr = append(destArr, sampleDest[:]...) + amountArr = append(amountArr, sample[:]...) + } + + rScript, err := DeserializeEthScript(redeemScript) + if err != nil { + return nil, err + } + + shash, _, err := GenTokenScriptHash(rScript) + if err != nil { + return nil, err + } + + var txHash [32]byte + var payloadHash [32]byte + + + // // Follows ERC191 signature scheme: https://github.com/ethereum/EIPs/issues/191 + // bytes32 txHash = keccak256( + // abi.encodePacked( + // "\x19Ethereum Signed Message:\n32", + // keccak256( + // abi.encodePacked( + // byte(0x19), + // byte(0), + // this, + // destinations, + // amounts, + // scriptHash + // ) + // ) + // ) + // ); + + + + payload := []byte{byte(0x19), byte(0)} + payload = append(payload, rScript.MultisigAddress.Bytes()...) + payload = append(payload, destArr...) + payload = append(payload, amountArr...) + payload = append(payload, shash[:]...) + + pHash := crypto.Keccak256(payload) + copy(payloadHash[:], pHash) + + txData := []byte{byte(0x19)} + txData = append(txData, []byte("Ethereum Signed Message:\n32")...) + txData = append(txData, payloadHash[:]...) + txnHash := crypto.Keccak256(txData) + copy(txHash[:], txnHash) + + sig, err := crypto.Sign(txHash[:], wallet.account.privateKey) + if err != nil { + log.Errorf("error signing in createmultisig : %v", err) + } + sigs = append(sigs, wi.Signature{InputIndex: 1, Signature: sig}) + + return sigs, err +} +*/ + +/* // Multisign - Combine signatures and optionally broadcast func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.TransactionOutput, sigs1 []wi.Signature, sigs2 []wi.Signature, redeemScript []byte, feePerByte uint64, broadcast bool) ([]byte, error) { @@ -867,6 +1772,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa return ret, err } +*/ // AddTransactionListener - add a txn listener func (wallet *ERC20Wallet) AddTransactionListener(callback func(wi.TransactionCallback)) { @@ -881,12 +1787,66 @@ func (wallet *ERC20Wallet) ReSyncBlockchain(fromTime time.Time) { // GetConfirmations - Return the number of confirmations and the height for a transaction func (wallet *ERC20Wallet) GetConfirmations(txid chainhash.Hash) (confirms, atHeight uint32, err error) { - return 0, 0, nil + hash := common.HexToHash(util.EnsureCorrectPrefix(txid.String())) + network := etherscan.Rinkby + if strings.Contains(wallet.client.url, "mainnet") { + network = etherscan.Mainnet + } + urlStr := fmt.Sprintf("https://%s.etherscan.io/api?module=proxy&action=eth_getTransactionByHash&txhash=%s&apikey=%s", + network, hash.String(), EtherScanAPIKey) + res, err := http.Get(urlStr) + if err != nil { + return 0, 0, err + } + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return 0, 0, err + } + if len(body) == 0 { + return 0, 0, errors.New("invalid txn hash") + } + var s map[string]interface{} + err = json.Unmarshal(body, &s) + if err != nil { + return 0, 0, err + } + + if s["result"] == nil { + return 0, 0, errors.New("invalid txn hash") + } + + if s["message"] != nil { + return 0, 0, nil + } + + result := s["result"].(map[string]interface{}) + + var d, conf int64 + if result["blockNumber"] != nil { + d, _ = strconv.ParseInt(result["blockNumber"].(string), 0, 64) + } else { + d = 0 + } + + n, err := wallet.client.HeaderByNumber(context.Background(), nil) + if err != nil { + return 0, 0, err + } + + if d != 0 { + conf = n.Number.Int64() - d + 1 + } else { + conf = 0 + } + + return uint32(conf), uint32(d), nil } // Close will stop the wallet daemon func (wallet *ERC20Wallet) Close() { // stop the wallet daemon + doneERC20 <- true + doneBalanceTickerERC20 <- true } // CreateAddress - used to generate a new address diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go index 09e5029a04..527a29f95c 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go @@ -382,10 +382,8 @@ func (wallet *EthereumWallet) CurrencyCode() string { } if wallet.params.Name == chaincfg.MainNetParams.Name { return "ETH" - } else { - return "TETH" } - //return "ETH" + return "TETH" } // IsDust Check if this amount is considered dust - 10000 wei @@ -1411,9 +1409,6 @@ func (wallet *EthereumWallet) ReSyncBlockchain(fromTime time.Time) { // GetConfirmations - Return the number of confirmations and the height for a transaction func (wallet *EthereumWallet) GetConfirmations(txid chainhash.Hash) (confirms, atHeight uint32, err error) { - // TODO: etherscan api is being used - // when mainnet is activated we may need a way to set the - // url correctly - done 6 April 2019 hash := common.HexToHash(util.EnsureCorrectPrefix(txid.String())) network := etherscan.Rinkby if strings.Contains(wallet.client.url, "mainnet") { diff --git a/vendor/github.com/OpenBazaar/multiwallet/multiwallet.go b/vendor/github.com/OpenBazaar/multiwallet/multiwallet.go index 2307e92834..8ac7ed5ade 100644 --- a/vendor/github.com/OpenBazaar/multiwallet/multiwallet.go +++ b/vendor/github.com/OpenBazaar/multiwallet/multiwallet.go @@ -98,6 +98,16 @@ func NewMultiWallet(cfg *config.Config) (MultiWallet, error) { } else { multiwallet[wallet.TestnetEthereum] = w } + case wallet.OBToken: + w, err = eth.NewERC20Wallet(coin, cfg.Params, cfg.Mnemonic, cfg.Proxy) + if err != nil { + return nil, err + } + if cfg.Params.Name == chaincfg.MainNetParams.Name { + multiwallet[wallet.OBToken] = w + } else { + multiwallet[wallet.TestnetOBToken] = w + } } } return multiwallet, nil diff --git a/vendor/github.com/OpenBazaar/wallet-interface/datastore.go b/vendor/github.com/OpenBazaar/wallet-interface/datastore.go index 4d91b9e0c6..1f3231280c 100644 --- a/vendor/github.com/OpenBazaar/wallet-interface/datastore.go +++ b/vendor/github.com/OpenBazaar/wallet-interface/datastore.go @@ -24,12 +24,14 @@ const ( Zcash = 133 BitcoinCash = 145 Ethereum = 60 + OBToken = 61 TestnetBitcoin = 1000000 TestnetLitecoin = 1000001 TestnetZcash = 1000133 TestnetBitcoinCash = 1000145 TestnetEthereum = 1000060 + TestnetOBToken = 1000061 ) func (c *CoinType) String() string { @@ -44,6 +46,8 @@ func (c *CoinType) String() string { return "Litecoin" case Ethereum: return "Ethereum" + case OBToken: + return "OBToken" case TestnetBitcoin: return "Testnet Bitcoin" case TestnetBitcoinCash: @@ -54,6 +58,8 @@ func (c *CoinType) String() string { return "Testnet Litecoin" case TestnetEthereum: return "Testnet Ethereum" + case TestnetOBToken: + return "Testnet OBToken" default: return "" } @@ -71,6 +77,8 @@ func (c *CoinType) CurrencyCode() string { return "LTC" case Ethereum: return "ETH" + case OBToken: + return "OBT" case TestnetBitcoin: return "TBTC" case TestnetBitcoinCash: @@ -81,6 +89,8 @@ func (c *CoinType) CurrencyCode() string { return "TLTC" case TestnetEthereum: return "TETH" + case TestnetOBToken: + return "TOBT" default: return "" } From 89637799a22fa07e66c57ecebfc2f82a0bb7c182 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Mon, 16 Mar 2020 23:01:11 +0530 Subject: [PATCH 2/7] enable obt wallet --- qa/testdata/eth_listing.json | 2 +- schema/constants.go | 8 ++++---- wallet/builder.go | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/qa/testdata/eth_listing.json b/qa/testdata/eth_listing.json index c731ae2dca..7670782d56 100644 --- a/qa/testdata/eth_listing.json +++ b/qa/testdata/eth_listing.json @@ -5,7 +5,7 @@ "contractType": "PHYSICAL_GOOD", "format": "FIXED_PRICE", "expiry": "2030-08-17T04:52:19.000Z", - "acceptedCurrencies": ["TETH"], + "acceptedCurrencies": ["TETH","TOBT"], "escrowTimeoutHours": 1080 }, "item": { diff --git a/schema/constants.go b/schema/constants.go index 68a92e9af4..2d8e92fd93 100644 --- a/schema/constants.go +++ b/schema/constants.go @@ -47,13 +47,13 @@ const ( EthereumRegistryAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" EthereumRegistryAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" - // OB Tokens + // OBToken OBTRegistryAddressMainnet = "0x5c69ccf91eab4ef80d9929b3c1b4d5bc03eb0981" OBTRegistryAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" OBTRegistryAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" - OBTAddressMainnet = "0x5c69ccf91eab4ef80d9929b3c1b4d5bc03eb0981" - OBTAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" - OBTAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" + OBTAddressMainnet = "0xe46ea07736e68df951df7b987dda453962ba7d5a" + OBTAddressRinkeby = "0xe46ea07736e68df951df7b987dda453962ba7d5a" + OBTAddressRopsten = "0xe46ea07736e68df951df7b987dda453962ba7d5a" DataPushNodeOne = "QmbwN82MVyBukT7WTdaQDppaACo62oUfma8dUa5R9nBFHm" DataPushNodeTwo = "QmPPg2qeF3n2KvTRXRZLaTwHCw8JxzF4uZK93RfMoDvf2o" diff --git a/wallet/builder.go b/wallet/builder.go index 31c51e7437..78a3d86831 100644 --- a/wallet/builder.go +++ b/wallet/builder.go @@ -89,6 +89,7 @@ func NewMultiWallet(cfg *WalletConfig) (multiwallet.MultiWallet, error) { enableAPIWallet[wallet.Litecoin] = cfg.ConfigFile.LTC } enableAPIWallet[wallet.Ethereum] = cfg.ConfigFile.ETH + enableAPIWallet[wallet.OBToken] = cfg.ConfigFile.OBT var newMultiwallet = make(multiwallet.MultiWallet) for coin, coinConfig := range enableAPIWallet { @@ -178,6 +179,18 @@ func createAPIWallet(coin wallet.CoinType, coinConfigOverrides *schema.CoinConfi return InvalidCoinType, nil, err } return actualCoin, w, nil + case wallet.OBToken: + if testnet { + actualCoin = wallet.TestnetOBToken + } else { + actualCoin = wallet.OBToken + } + //actualCoin = wallet.Ethereum + w, err := eth.NewERC20Wallet(*coinConfig, cfg.Params, cfg.Mnemonic, cfg.Proxy) + if err != nil { + return InvalidCoinType, nil, err + } + return actualCoin, w, nil } return InvalidCoinType, nil, fmt.Errorf("unable to create wallet for unknown coin %s", coin.String()) } @@ -299,6 +312,9 @@ func prepareAPICoinConfig(coin wallet.CoinType, override *schema.CoinConfig, wal case wallet.Ethereum: defaultConfig = defaultConfigSet.ETH defaultCoinOptions = schema.EthereumDefaultOptions() + case wallet.OBToken: + defaultConfig = defaultConfigSet.OBT + defaultCoinOptions = schema.OBTDefaultOptions() } if testnet { From 43b9a972322eecadcf07a873688ffaaae5a3cb97 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Mon, 23 Mar 2020 00:13:41 +0530 Subject: [PATCH 3/7] fix the erc20 contract address --- qa/testdata/eth_listing.json | 2 +- schema/constants.go | 6 +- .../OpenBazaar/go-ethwallet/wallet/client.go | 3 +- .../go-ethwallet/wallet/erc20_wallet.go | 104 +++++++++++++++--- .../OpenBazaar/go-ethwallet/wallet/wallet.go | 10 +- 5 files changed, 101 insertions(+), 24 deletions(-) diff --git a/qa/testdata/eth_listing.json b/qa/testdata/eth_listing.json index 7670782d56..4946f8c5ba 100644 --- a/qa/testdata/eth_listing.json +++ b/qa/testdata/eth_listing.json @@ -18,7 +18,7 @@ "name": "A", "currencyType": "A" }, - "bigPrice": "4500000000000000", + "bigPrice": "45000000000000", "tags": [ "tshirts", "clothing", diff --git a/schema/constants.go b/schema/constants.go index 2d8e92fd93..f0b39ac1c6 100644 --- a/schema/constants.go +++ b/schema/constants.go @@ -51,9 +51,9 @@ const ( OBTRegistryAddressMainnet = "0x5c69ccf91eab4ef80d9929b3c1b4d5bc03eb0981" OBTRegistryAddressRinkeby = "0x5cEF053c7b383f430FC4F4e1ea2F7D31d8e2D16C" OBTRegistryAddressRopsten = "0x403d907982474cdd51687b09a8968346159378f3" - OBTAddressMainnet = "0xe46ea07736e68df951df7b987dda453962ba7d5a" - OBTAddressRinkeby = "0xe46ea07736e68df951df7b987dda453962ba7d5a" - OBTAddressRopsten = "0xe46ea07736e68df951df7b987dda453962ba7d5a" + OBTAddressMainnet = "0x6b175474e89094c44da98b954eedeac495271d0f" //"0xe46ea07736e68df951df7b987dda453962ba7d5a" + OBTAddressRinkeby = "0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea" //"0xe46ea07736e68df951df7b987dda453962ba7d5a" + OBTAddressRopsten = "0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea" //"0xe46ea07736e68df951df7b987dda453962ba7d5a" DataPushNodeOne = "QmbwN82MVyBukT7WTdaQDppaACo62oUfma8dUa5R9nBFHm" DataPushNodeTwo = "QmPPg2qeF3n2KvTRXRZLaTwHCw8JxzF4uZK93RfMoDvf2o" diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go index e1d1d0210b..87004942df 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go @@ -172,7 +172,8 @@ func (client *EthClient) TransferToken(from *Account, toAddress common.Address, if err != nil { return common.BytesToHash([]byte{}), err } - rawTx := types.NewTransaction(nonce, tokenAddress, value, gasLimit, gasPrice, data) + gasLimit = 500000 + rawTx := types.NewTransaction(nonce, tokenAddress, big.NewInt(0), gasLimit, gasPrice, data) signedTx, err := from.SignTransaction(types.HomesteadSigner{}, rawTx) //types.SignTx(tx, types.HomesteadSigner{}, privateKey) if err != nil { return common.BytesToHash([]byte{}), err diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index 39e7f1c8bd..20b4a608bc 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -56,6 +56,7 @@ type ERC20Wallet struct { deployAddressMain common.Address deployAddressRopsten common.Address deployAddressRinkeby common.Address + currentdeployAddress common.Address token *Token listeners []func(wi.TransactionCallback) } @@ -85,6 +86,7 @@ type TokenDetail struct { deployAddressMain common.Address deployAddressRopsten common.Address deployAddressRinkeby common.Address + currentdeployAddress common.Address } // NewERC20Wallet will return a reference to the ERC20 Wallet @@ -151,14 +153,20 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str token.deployAddressMain = common.HexToAddress(deployAddrMain.(string)) if deployAddrRopsten, ok = cfg.Options["RopstenAddress"]; ok { - token.deployAddressMain = common.HexToAddress(deployAddrRopsten.(string)) + token.deployAddressRopsten = common.HexToAddress(deployAddrRopsten.(string)) } if deployAddrRinkeby, ok = cfg.Options["RinkebyAddress"]; ok { token.deployAddressRinkeby = common.HexToAddress(deployAddrRinkeby.(string)) } - erc20Token, err := NewToken(token.deployAddressMain, client) + token.currentdeployAddress = token.deployAddressMain + if strings.Contains(cfg.ClientAPIs[0], "rinkeby") { + token.currentdeployAddress = token.deployAddressRinkeby + } else if strings.Contains(cfg.ClientAPIs[0], "ropsten") { + token.currentdeployAddress = token.deployAddressRopsten + } + erc20Token, err := NewToken(token.currentdeployAddress, client) if err != nil { log.Errorf("error initilaizing erc20 token failed: %s", err.Error()) return nil, err @@ -184,6 +192,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str deployAddressMain: token.deployAddressMain, deployAddressRopsten: token.deployAddressRopsten, deployAddressRinkeby: token.deployAddressRinkeby, + currentdeployAddress: token.currentdeployAddress, token: erc20Token, listeners: []func(wi.TransactionCallback){}, }, nil @@ -196,7 +205,7 @@ func (wallet *ERC20Wallet) Params() *chaincfg.Params { // GetBalance returns the balance for the wallet func (wallet *ERC20Wallet) GetBalance() (*big.Int, error) { - return wallet.client.GetTokenBalance(wallet.account.Address(), wallet.deployAddressMain) + return wallet.client.GetTokenBalance(wallet.account.Address(), wallet.currentdeployAddress) } // GetUnconfirmedBalance returns the unconfirmed balance for the wallet @@ -207,7 +216,7 @@ func (wallet *ERC20Wallet) GetUnconfirmedBalance() (*big.Int, error) { // Transfer will transfer the amount from this wallet to the spec address func (wallet *ERC20Wallet) Transfer(to string, value *big.Int, spendAll bool, fee big.Int) (common.Hash, error) { toAddress := common.HexToAddress(to) - return wallet.client.TransferToken(wallet.account, toAddress, wallet.deployAddressMain, value, spendAll, fee) + return wallet.client.TransferToken(wallet.account, toAddress, wallet.currentdeployAddress, value, spendAll, fee) } // Start will start the wallet daemon @@ -508,17 +517,84 @@ func (wallet *ERC20Wallet) Transactions() ([]wi.Txn, error) { // GetTransaction - Get info on a specific transaction func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { - tx, _, err := wallet.client.GetTransaction(common.HexToHash(txid.String())) + // tx, _, err := wallet.client.GetTransaction(common.HexToHash(txid.String())) + // if err != nil { + // return wi.Txn{}, err + // } + // return wi.Txn{ + // Txid: tx.Hash().String(), + // Value: tx.Value().String(), + // Height: 0, + // Timestamp: time.Now(), + // WatchOnly: false, + // Bytes: tx.Data(), + // }, nil + tx, _, err := wallet.client.GetTransaction(common.HexToHash(util.EnsureCorrectPrefix(txid.String()))) + if err != nil { + return wi.Txn{}, err + } + + chainID, err := wallet.client.NetworkID(context.Background()) if err != nil { return wi.Txn{}, err } + + msg, err := tx.AsMessage(types.NewEIP155Signer(chainID)) // HomesteadSigner{}) + if err != nil { + return wi.Txn{}, err + } + + //value := tx.Value().String() + fromAddr := msg.From() + toAddr := msg.To() + valueSub := big.NewInt(5000000) + value := tx.Value() + + if strings.HasPrefix(hexutil.Encode(msg.Data()), "0xa9059cbb") { + value = big.NewInt(0).SetBytes(msg.Data()[36:]) + } + + if tx.To().String() == wallet.currentdeployAddress.String() { + toAddr = wallet.address.address + valueSub = value + } else { + v, err := wallet.registry.GetRecommendedVersion(nil, "escrow") + if err == nil { + if tx.To().String() == v.Implementation.String() { + toAddr = wallet.address.address + } + if msg.Value().Cmp(valueSub) > 0 { + valueSub = msg.Value() + } + } + } + return wi.Txn{ - Txid: tx.Hash().String(), - Value: tx.Value().String(), - Height: 0, - Timestamp: time.Now(), - WatchOnly: false, - Bytes: tx.Data(), + Txid: util.EnsureCorrectPrefix(tx.Hash().Hex()), + Value: value.String(), + Height: 0, + Timestamp: time.Now(), + WatchOnly: false, + Bytes: tx.Data(), + ToAddress: util.EnsureCorrectPrefix(toAddr.String()), + FromAddress: util.EnsureCorrectPrefix(msg.From().Hex()), + Outputs: []wi.TransactionOutput{ + { + Address: EthAddress{toAddr}, + Value: *valueSub, + Index: 0, + }, + { + Address: EthAddress{&fromAddr}, + Value: *valueSub, + Index: 1, + }, + { + Address: EthAddress{msg.To()}, + Value: *valueSub, + Index: 2, + }, + }, }, nil } @@ -969,7 +1045,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value tx, err = smtct.AddTokenTransaction(auth, script.Buyer, script.Seller, script.Moderator, script.Threshold, script.Timeout, shash, - value, script.TxnID, wallet.deployAddressMain) + value, script.TxnID, wallet.currentdeployAddress) if err == nil { h = tx.Hash() @@ -988,7 +1064,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value tx, err = smtct.AddTokenTransaction(auth, script.Buyer, script.Seller, script.Moderator, script.Threshold, script.Timeout, shash, - value, script.TxnID, wallet.deployAddressMain) + value, script.TxnID, wallet.currentDeployAddress) if err == nil { h = tx.Hash() @@ -1539,7 +1615,7 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho builder.Buyer = ecKeys[0] builder.Seller = ecKeys[1] builder.MultisigAddress = ver.Implementation - builder.TokenAddress = wallet.deployAddressMain + builder.TokenAddress = wallet.currentDeployAddress if threshold > 1 { builder.Moderator = ecKeys[2] diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go index 60fb76a422..f1fc6d1137 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/wallet.go @@ -663,11 +663,11 @@ func (wallet *EthereumWallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { // Spend - Send ether to an external wallet func (wallet *EthereumWallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string, spendAll bool) (*chainhash.Hash, error) { var ( - hash common.Hash - h *chainhash.Hash + hash common.Hash + h *chainhash.Hash watchOnly bool - nonce int32 - err error + nonce int32 + err error ) actualRecipient := addr @@ -1501,7 +1501,7 @@ func (wallet *EthereumWallet) CreateAddress() (common.Address, error) { // PrintKeys - used to print the keys for this wallet func (wallet *EthereumWallet) PrintKeys() { privateKeyBytes := crypto.FromECDSA(wallet.account.privateKey) - log.Debug(string(privateKeyBytes)) + log.Debug(hexutil.Encode(privateKeyBytes)[2:]) publicKey := wallet.account.privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { From 5e13de244fa8ce4b4cf07bba2f9e71db50ef809a Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Tue, 24 Mar 2020 12:53:37 +0530 Subject: [PATCH 4/7] fix token addresses for direct --- qa/eth_dispute_close_split.py | 2 +- .../OpenBazaar/go-ethwallet/wallet/client.go | 2 + .../go-ethwallet/wallet/erc20_wallet.go | 97 ++++++++++++++----- 3 files changed, 77 insertions(+), 24 deletions(-) diff --git a/qa/eth_dispute_close_split.py b/qa/eth_dispute_close_split.py index a011764814..7d61da8d83 100644 --- a/qa/eth_dispute_close_split.py +++ b/qa/eth_dispute_close_split.py @@ -52,7 +52,7 @@ def run_test(self): resp = json.loads(r.text) raise TestFailure("EthDisputeCloseSplitTest - FAIL: Moderator POST failed. Reason: %s", resp["reason"]) moderatorId = charlie["peerId"] - time.sleep(4) + time.sleep(40) # post profile for alice with open('testdata/profile.json') as profile_file: diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go index 87004942df..57ad3326a6 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/client.go @@ -47,6 +47,7 @@ type EthClient struct { eClient *etherscan.Client ws *websocket.Conn url string + wsurl string } var txns []wi.Txn @@ -81,6 +82,7 @@ func NewEthClient(url string) (*EthClient, error) { Client: conn, eClient: econn, url: url, + wsurl: wsURL, ws: ws, }, nil diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index 20b4a608bc..d1c6d0ea51 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -5,6 +5,7 @@ import ( "context" "crypto/ecdsa" "encoding/binary" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -365,10 +366,24 @@ func (wallet *ERC20Wallet) MasterPublicKey() *hd.ExtendedKey { // ChildKey Generate a child key using the given chaincode. The key is used in multisig transactions. // For most implementations this should just be child key 0. func (wallet *ERC20Wallet) ChildKey(keyBytes []byte, chaincode []byte, isPrivateKey bool) (*hd.ExtendedKey, error) { - if isPrivateKey { - return wallet.MasterPrivateKey(), nil + parentFP := []byte{0x00, 0x00, 0x00, 0x00} + version := []byte{0x04, 0x88, 0xad, 0xe4} // starts with xprv + if !isPrivateKey { + version = []byte{0x04, 0x88, 0xb2, 0x1e} } - return wallet.MasterPublicKey(), nil + /* + hdKey := hd.NewExtendedKey( + version, + keyBytes, + chaincode, + parentFP, + 0, + 0, + isPrivateKey) + return hdKey.Child(0) + */ + + return hd.NewExtendedKey(version, keyBytes, chaincode, parentFP, 0, 0, isPrivateKey), nil } // CurrentAddress - Get the current address for the given purpose @@ -381,10 +396,38 @@ func (wallet *ERC20Wallet) NewAddress(purpose wi.KeyPurpose) btcutil.Address { return *wallet.address } +func ethTokenScriptToAddr(addr string) (common.Address, error) { + rScriptBytes, err := hex.DecodeString(addr) + if err != nil { + return common.Address{}, err + } + rScript, err := DeserializeEthScript(rScriptBytes) + if err != nil { + return common.Address{}, err + } + _, sHash, err := GenTokenScriptHash(rScript) + if err != nil { + return common.Address{}, err + } + return common.HexToAddress(sHash), nil +} + // DecodeAddress - Parse the address string and return an address interface func (wallet *ERC20Wallet) DecodeAddress(addr string) (btcutil.Address, error) { - ethAddr := common.HexToAddress(addr) - return EthAddress{ðAddr}, nil + var ( + ethAddr common.Address + err error + ) + if len(addr) > 64 { + ethAddr, err = ethTokenScriptToAddr(addr) + if err != nil { + log.Error(err.Error()) + } + } else { + ethAddr = common.HexToAddress(addr) + } + + return EthAddress{ðAddr}, err } // ScriptToAddress - ? @@ -443,7 +486,6 @@ func (wallet *ERC20Wallet) Balance() (confirmed, unconfirmed int64) { } */ -// Transactions - Returns a list of transactions for this wallet // TransactionsFromBlock - Returns a list of transactions for this wallet begining from the specified block func (wallet *ERC20Wallet) TransactionsFromBlock(startBlock *int) ([]wi.Txn, error) { txns, err := wallet.client.eClient.NormalTxByAddress(util.EnsureCorrectPrefix(wallet.account.Address().String()), startBlock, nil, @@ -630,6 +672,7 @@ func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { // Spend - Send ether to an external wallet func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string, spendAll bool) (*chainhash.Hash, error) { + fmt.Println(",,, in erc20 spend ..... ", amount.String(), " ", addr.String(), referenceID) var hash common.Hash var h *chainhash.Hash var err error @@ -665,13 +708,13 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel if err != nil { return nil, err } - _, scrHash, err := GenScriptHash(ethScript) - if err != nil { - log.Error(err.Error()) - } - addrScrHash := common.HexToAddress(scrHash) - actualRecipient = EthAddress{address: &addrScrHash} - hash, _, err = wallet.callAddTransaction(ethScript, &amount, feeLevel) + // _, scrHash, err := GenTokenScriptHash(ethScript) + // if err != nil { + // log.Error(err.Error()) + // } + //addrScrHash := ethScript. //common.HexToAddress(scrHash) + actualRecipient = EthAddress{address: ðScript.Seller} //EthAddress{address: &addrScrHash} + hash, _, err = wallet.callAddTokenTransaction(ethScript, &amount, feeLevel) if err != nil { log.Errorf("error call add txn: %v", err) return nil, wi.ErrInsufficientFunds @@ -963,7 +1006,7 @@ func (wallet *ERC20Wallet) ExchangeRates() wi.ExchangeRates { return wallet.exchangeRates } -func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value *big.Int) (common.Hash, error) { +func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value *big.Int, feeLevel wi.FeeLevel) (common.Hash, uint64, error) { h := common.BigToHash(big.NewInt(0)) @@ -984,9 +1027,16 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value auth.GasLimit = 4000000 // in units auth.GasPrice = gasPrice + // lets check if the caller has enough balance to make the + // multisign call + if !wallet.balanceCheck(feeLevel, *big.NewInt(0)) { + // the wallet does not have the required balance + return h, nonce, wi.ErrInsufficientFunds + } + shash, _, err := GenTokenScriptHash(script) if err != nil { - return h, err + return h, 0, err } smtct, err := NewEscrow(script.MultisigAddress, wallet.client) @@ -999,7 +1049,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value tx, err = wallet.token.Approve(auth, script.MultisigAddress, value) if err != nil { - return common.BigToHash(big.NewInt(0)), err + return common.BigToHash(big.NewInt(0)), 0, err } //time.Sleep(2 * time.Minute) @@ -1007,7 +1057,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value if err != nil { log.Errorf("error fetching latest blk: %v", err) } - tclient, err := ethclient.Dial("wss://rinkeby.infura.io/ws") + tclient, err := ethclient.Dial(wallet.client.wsurl) if err != nil { log.Errorf("error establishing ws conn: %v", err) } @@ -1020,7 +1070,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value logs := make(chan types.Log) sub1, err := tclient.SubscribeFilterLogs(context.Background(), query, logs) if err != nil { - return common.BigToHash(big.NewInt(0)), err + return common.BigToHash(big.NewInt(0)), 0, err } defer sub1.Unsubscribe() flag := false @@ -1071,7 +1121,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value } */ - return h, err + return h, nonce, err } @@ -1107,7 +1157,7 @@ func (wallet *ERC20Wallet) callAddTransaction(script EthRedeemScript, value *big return h, nonce, wi.ErrInsufficientFunds } - shash, _, err := GenScriptHash(script) + shash, _, err := GenTokenScriptHash(script) if err != nil { return h, nonce, err } @@ -1183,6 +1233,7 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho builder.Buyer = ecKeys[0] builder.Seller = ecKeys[1] builder.MultisigAddress = ver.Implementation + builder.TokenAddress = wallet.currentdeployAddress if threshold > 1 { builder.Moderator = ecKeys[2] @@ -1320,7 +1371,7 @@ func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, ou amountArr = append(amountArr, sample[:]...) } - shash, _, err := GenScriptHash(rScript) + shash, _, err := GenTokenScriptHash(rScript) if err != nil { return nil, err } @@ -1475,7 +1526,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa vSlice = append(vSlice, v) } - shash, _, err := GenScriptHash(rScript) + shash, _, err := GenTokenScriptHash(rScript) if err != nil { return nil, err } @@ -1541,7 +1592,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa Bytes: tx.Data()}) // this is a pending txn - _, scrHash, err := GenScriptHash(rScript) + _, scrHash, err := GenTokenScriptHash(rScript) if err != nil { log.Error(err.Error()) } From 284e80e4770bb8835ea4e7651fca4d2b667a8a26 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Thu, 26 Mar 2020 00:11:11 +0530 Subject: [PATCH 5/7] fix the moderated orders --- .../go-ethwallet/wallet/erc20_wallet.go | 177 +++++++----------- 1 file changed, 64 insertions(+), 113 deletions(-) diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index d1c6d0ea51..2237809b76 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/nanmu42/etherscan-api" + "github.com/op/go-logging" "golang.org/x/net/proxy" "github.com/OpenBazaar/go-ethwallet/util" @@ -40,6 +41,7 @@ import ( var doneERC20, doneBalanceTickerERC20 chan bool var currencyDefinitionERC20 wi.CurrencyDefinition +var logERC = logging.MustGetLogger("ercwallet") // ERC20Wallet is the wallet implementation for ethereum type ERC20Wallet struct { @@ -94,13 +96,13 @@ type TokenDetail struct { func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic string, proxy proxy.Dialer) (*ERC20Wallet, error) { client, err := NewEthClient(cfg.ClientAPIs[0] + "/" + InfuraAPIKey) if err != nil { - log.Errorf("error initializing wallet: %v", err) + logERC.Errorf("error initializing wallet: %v", err) return nil, err } var myAccount *Account myAccount, err = NewAccountFromMnemonic(mnemonic, "", params) if err != nil { - log.Errorf("mnemonic based pk generation failed: %s", err.Error()) + logERC.Errorf("mnemonic based pk generation failed: %s", err.Error()) return nil, err } addr := myAccount.Address() @@ -116,7 +118,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str registryKey = "RopstenRegistryAddress" } if regAddr, ok = cfg.Options[registryKey]; !ok { - log.Errorf("ethereum registry not found: %s", cfg.Options[registryKey]) + logERC.Errorf("ethereum registry not found: %s", cfg.Options[registryKey]) return nil, err } @@ -124,7 +126,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str reg, err := NewRegistry(common.HexToAddress(ethConfig.RegistryAddress), client) if err != nil { - log.Errorf("error initilaizing contract failed: %s", err.Error()) + logERC.Errorf("error initilaizing contract failed: %s", err.Error()) return nil, err } er := NewEthereumPriceFetcher(proxy) @@ -133,21 +135,21 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str var name, symbol, deployAddrMain, deployAddrRopsten, deployAddrRinkeby interface{} if name, ok = cfg.Options["Name"]; !ok { - log.Errorf("erc20 token name not found: %s", cfg.Options["Name"]) + logERC.Errorf("erc20 token name not found: %s", cfg.Options["Name"]) return nil, err } token.name = name.(string) if symbol, ok = cfg.Options["Symbol"]; !ok { - log.Errorf("erc20 token symbol not found: %s", cfg.Options["Symbol"]) + logERC.Errorf("erc20 token symbol not found: %s", cfg.Options["Symbol"]) return nil, err } token.symbol = symbol.(string) if deployAddrMain, ok = cfg.Options["MainNetAddress"]; !ok { - log.Errorf("erc20 token address not found: %s", cfg.Options["MainNetAddress"]) + logERC.Errorf("erc20 token address not found: %s", cfg.Options["MainNetAddress"]) return nil, err } @@ -169,7 +171,7 @@ func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic str } erc20Token, err := NewToken(token.currentdeployAddress, client) if err != nil { - log.Errorf("error initilaizing erc20 token failed: %s", err.Error()) + logERC.Errorf("error initilaizing erc20 token failed: %s", err.Error()) return nil, err } @@ -244,7 +246,7 @@ func (wallet *ERC20Wallet) Start() { go func(txnData []byte) { _, err := wallet.checkTxnRcpt(&hash, txnData) if err != nil { - log.Errorf(err.Error()) + logERC.Errorf(err.Error()) } }(txn.Bytes) } @@ -259,7 +261,7 @@ func (wallet *ERC20Wallet) Start() { currentBalance, err := wallet.GetBalance() if err != nil { - log.Infof("err fetching initial balance: %v", err) + logERC.Infof("err fetching initial balance: %v", err) } currentTip, _ := wallet.ChainTip() @@ -271,7 +273,7 @@ func (wallet *ERC20Wallet) Start() { // fetch the current balance fetchedBalance, err := wallet.GetBalance() if err != nil { - log.Infof("err fetching balance at %v: %v", time.Now(), err) + logERC.Infof("err fetching balance at %v: %v", time.Now(), err) continue } if fetchedBalance.Cmp(currentBalance) != 0 { @@ -355,7 +357,7 @@ func (wallet *ERC20Wallet) MasterPublicKey() *hd.ExtendedKey { publicKey := wallet.account.privateKey.Public() publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) if !ok { - log.Fatal("error casting public key to ECDSA") + logERC.Fatal("error casting public key to ECDSA") } publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA) @@ -421,7 +423,7 @@ func (wallet *ERC20Wallet) DecodeAddress(addr string) (btcutil.Address, error) { if len(addr) > 64 { ethAddr, err = ethTokenScriptToAddr(addr) if err != nil { - log.Error(err.Error()) + logERC.Error(err.Error()) } } else { ethAddr = common.HexToAddress(addr) @@ -491,7 +493,7 @@ func (wallet *ERC20Wallet) TransactionsFromBlock(startBlock *int) ([]wi.Txn, err txns, err := wallet.client.eClient.NormalTxByAddress(util.EnsureCorrectPrefix(wallet.account.Address().String()), startBlock, nil, 1, 0, false) if err != nil { - log.Error("err fetching transactions : ", err) + logERC.Error("err fetching transactions : ", err) return []wi.Txn{}, nil } @@ -594,6 +596,10 @@ func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { if strings.HasPrefix(hexutil.Encode(msg.Data()), "0xa9059cbb") { value = big.NewInt(0).SetBytes(msg.Data()[36:]) + } else if strings.HasPrefix(hexutil.Encode(msg.Data()), "0x57bced76") { + b := msg.Data() + value = big.NewInt(0).SetBytes(b[len(b)-(3*32) : len(b)-(2*32)]) + valueSub = value } if tx.To().String() == wallet.currentdeployAddress.String() { @@ -656,7 +662,7 @@ func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { est, err := wallet.client.GetEthGasStationEstimate() ret := big.NewInt(0) if err != nil { - log.Errorf("err fetching ethgas station data: %v", err) + logERC.Errorf("err fetching ethgas station data: %v", err) return *ret } switch feeLevel { @@ -672,7 +678,6 @@ func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { // Spend - Send ether to an external wallet func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string, spendAll bool) (*chainhash.Hash, error) { - fmt.Println(",,, in erc20 spend ..... ", amount.String(), " ", addr.String(), referenceID) var hash common.Hash var h *chainhash.Hash var err error @@ -708,15 +713,15 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel if err != nil { return nil, err } - // _, scrHash, err := GenTokenScriptHash(ethScript) - // if err != nil { - // log.Error(err.Error()) - // } - //addrScrHash := ethScript. //common.HexToAddress(scrHash) - actualRecipient = EthAddress{address: ðScript.Seller} //EthAddress{address: &addrScrHash} + _, scrHash, err := GenTokenScriptHash(ethScript) + if err != nil { + logERC.Error(err.Error()) + } + addrScrHash := common.HexToAddress(scrHash) + actualRecipient = EthAddress{address: &addrScrHash} //EthAddress{address: ðScript.Seller} //EthAddress{address: &addrScrHash} hash, _, err = wallet.callAddTokenTransaction(ethScript, &amount, feeLevel) if err != nil { - log.Errorf("error call add txn: %v", err) + logERC.Errorf("error call add txn: %v", err) return nil, wi.ErrInsufficientFunds } } else { @@ -744,7 +749,7 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel if err == nil { err0 := wallet.db.Txns().Put(data, ut.NormalizeAddress(hash.Hex()), "0", 0, time.Now(), true) if err0 != nil { - log.Error(err0.Error()) + logERC.Error(err0.Error()) } } } @@ -789,7 +794,7 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel } hash, err = wallet.callAddTokenTransaction(ethScript, &amount) if err != nil { - log.Errorf("error call add token txn: %v", err) + logERC.Errorf("error call add token txn: %v", err) } } else { hash, err = wallet.Transfer(addr.String(), &amount) @@ -898,6 +903,7 @@ func (wallet *ERC20Wallet) callListeners(txnCB wi.TransactionCallback) { } } +// AssociateTransactionWithOrder is used to transition order state func (wallet *ERC20Wallet) AssociateTransactionWithOrder(txnCB wi.TransactionCallback) { for _, l := range wallet.listeners { go l(txnCB) @@ -914,7 +920,7 @@ func (wallet *ERC20Wallet) checkTxnRcpt(hash *common.Hash, data []byte) (*common rcpt, err = wallet.client.TransactionReceipt(context.Background(), *hash) if err != nil { - log.Infof("fetching txn rcpt: %v", err) + logERC.Infof("fetching txn rcpt: %v", err) } if rcpt != nil { @@ -928,7 +934,7 @@ func (wallet *ERC20Wallet) checkTxnRcpt(hash *common.Hash, data []byte) (*common } err = wallet.db.Txns().Delete(chash) if err != nil { - log.Errorf("err deleting the pending txn : %v", err) + logERC.Errorf("err deleting the pending txn : %v", err) } n := new(big.Int) n, _ = n.SetString(pTxn.Amount, 10) @@ -986,7 +992,7 @@ func (wallet *ERC20Wallet) balanceCheck(feeLevel wi.FeeLevel, amount big.Int) bo requiredBalance = new(big.Int).Add(requiredBalance, &amount) currentBalance, err := wallet.GetBalance() if err != nil { - log.Error("err fetching erc20 wallet balance") + logERC.Error("err fetching erc20 wallet balance") currentBalance = big.NewInt(0) } if requiredBalance.Cmp(currentBalance) > 0 { @@ -1014,11 +1020,11 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value fromAddress := wallet.account.Address() nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } auth := bind.NewKeyedTransactor(wallet.account.privateKey) @@ -1041,7 +1047,7 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value smtct, err := NewEscrow(script.MultisigAddress, wallet.client) if err != nil { - log.Fatalf("error initilaizing contract failed: %s", err.Error()) + logERC.Fatalf("error initilaizing contract failed: %s", err.Error()) } var tx *types.Transaction @@ -1055,11 +1061,11 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value //time.Sleep(2 * time.Minute) header, err := wallet.client.HeaderByNumber(context.Background(), nil) if err != nil { - log.Errorf("error fetching latest blk: %v", err) + logERC.Errorf("error fetching latest blk: %v", err) } tclient, err := ethclient.Dial(wallet.client.wsurl) if err != nil { - log.Errorf("error establishing ws conn: %v", err) + logERC.Errorf("error establishing ws conn: %v", err) } query := ethereum.FilterQuery{ @@ -1077,14 +1083,14 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value for !flag { select { case err := <-sub1.Err(): - log.Fatal(err) + logERC.Fatal(err) case vLog := <-logs: - //fmt.Println(vLog) // pointer to event log + //logERC.Info(vLog) // pointer to event log //spew.Dump(vLog) - //fmt.Println(vLog.Topics[0]) - fmt.Println(vLog.Address.String()) + //logERC.Info(vLog.Topics[0]) + logERC.Info(vLog.Address.String()) if tx.Hash() == vLog.TxHash { - fmt.Println("we have found the approval ...") + logERC.Info("we have found the approval ...") //time.Sleep(2 * time.Minute) spew.Dump(vLog) nonce, _ = wallet.client.PendingNonceAt(context.Background(), fromAddress) @@ -1121,61 +1127,6 @@ func (wallet *ERC20Wallet) callAddTokenTransaction(script EthRedeemScript, value } */ - return h, nonce, err - -} - -func (wallet *ERC20Wallet) callAddTransaction(script EthRedeemScript, value *big.Int, feeLevel wi.FeeLevel) (common.Hash, uint64, error) { - - h := common.BigToHash(big.NewInt(0)) - - // call registry to get the deployed address for the escrow ct - fromAddress := wallet.account.Address() - nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) - if err != nil { - log.Fatal(err) - } - gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) - if err != nil { - log.Fatal(err) - } - gasPriceETHGAS := wallet.GetFeePerByte(feeLevel) - if gasPriceETHGAS.Int64() < gasPrice.Int64() { - gasPriceETHGAS = *gasPrice - } - auth := bind.NewKeyedTransactor(wallet.account.privateKey) - - auth.Nonce = big.NewInt(int64(nonce)) - auth.Value = value // in wei - auth.GasLimit = maxGasLimit // in units - auth.GasPrice = gasPrice - - // lets check if the caller has enough balance to make the - // multisign call - if !wallet.balanceCheck(feeLevel, *big.NewInt(0)) { - // the wallet does not have the required balance - return h, nonce, wi.ErrInsufficientFunds - } - - shash, _, err := GenTokenScriptHash(script) - if err != nil { - return h, nonce, err - } - - smtct, err := NewEscrow(script.MultisigAddress, wallet.client) - if err != nil { - log.Fatalf("error initilaizing contract failed: %s", err.Error()) - } - - var tx *types.Transaction - tx, err = smtct.AddTransaction(auth, script.Buyer, script.Seller, - script.Moderator, script.Threshold, script.Timeout, shash, script.TxnID) - if err == nil { - h = tx.Hash() - } else { - return h, 0, err - } - txns = append(txns, wi.Txn{ Txid: tx.Hash().Hex(), Value: value.String(), @@ -1218,7 +1169,7 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho ver, err := wallet.registry.GetRecommendedVersion(nil, "escrow") if err != nil { - log.Fatal(err) + logERC.Fatal(err) } if util.IsZeroAddress(ver.Implementation) { @@ -1264,7 +1215,7 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho scriptKey := append(addr.Bytes(), redeemScript...) err = wallet.db.WatchedScripts().Put(scriptKey) if err != nil { - log.Errorf("err saving the redeemscript: %v", err) + logERC.Errorf("err saving the redeemscript: %v", err) } return retAddr, redeemScript, nil @@ -1412,13 +1363,13 @@ func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, ou txData = append(txData, []byte("Ethereum Signed Message:\n32")...) txData = append(txData, payloadHash[:]...) txnHash := crypto.Keccak256(txData) - log.Debugf("txnHash : %s", hexutil.Encode(txnHash)) - log.Debugf("phash : %s", hexutil.Encode(payloadHash[:])) + logERC.Debugf("txnHash : %s", hexutil.Encode(txnHash)) + logERC.Debugf("phash : %s", hexutil.Encode(payloadHash[:])) copy(txHash[:], txnHash) sig, err := crypto.Sign(txHash[:], wallet.account.privateKey) if err != nil { - log.Errorf("error signing in createmultisig : %v", err) + logERC.Errorf("error signing in createmultisig : %v", err) } sigs = append(sigs, wi.Signature{InputIndex: 1, Signature: sig}) @@ -1533,7 +1484,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa smtct, err := NewEscrow(rScript.MultisigAddress, wallet.client) if err != nil { - log.Fatalf("error initializing contract failed: %s", err.Error()) + logERC.Fatalf("error initializing contract failed: %s", err.Error()) } destinations := []common.Address{} @@ -1550,11 +1501,11 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa fromAddress := wallet.account.Address() nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } auth := bind.NewKeyedTransactor(wallet.account.privateKey) @@ -1568,7 +1519,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa requiredBalance := new(big.Int).Mul(gasPrice, big.NewInt(maxGasLimit)) currentBalance, err := wallet.GetBalance() if err != nil { - log.Error("err fetching eth wallet balance") + logERC.Error("err fetching eth wallet balance") currentBalance = big.NewInt(0) } @@ -1594,7 +1545,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa // this is a pending txn _, scrHash, err := GenTokenScriptHash(rScript) if err != nil { - log.Error(err.Error()) + logERC.Error(err.Error()) } data, err := SerializePendingTxn(PendingTxn{ TxnID: tx.Hash(), @@ -1607,7 +1558,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa if err == nil { err0 := wallet.db.Txns().Put(data, ut.NormalizeAddress(tx.Hash().Hex()), "0", 0, time.Now(), true) if err0 != nil { - log.Error(err0.Error()) + logERC.Error(err0.Error()) } } @@ -1651,7 +1602,7 @@ func (wallet *ERC20Wallet) GenerateMultisigScript(keys []hd.ExtendedKey, thresho ver, err := wallet.registry.GetRecommendedVersion(nil, "escrow") if err != nil { - log.Fatal(err) + logERC.Fatal(err) } if util.IsZeroAddress(ver.Implementation) { @@ -1790,7 +1741,7 @@ func (wallet *ERC20Wallet) CreateMultisigSignature(ins []wi.TransactionInput, ou sig, err := crypto.Sign(txHash[:], wallet.account.privateKey) if err != nil { - log.Errorf("error signing in createmultisig : %v", err) + logERC.Errorf("error signing in createmultisig : %v", err) } sigs = append(sigs, wi.Signature{InputIndex: 1, Signature: sig}) @@ -1857,7 +1808,7 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa smtct, err := NewEscrow(rScript.MultisigAddress, wallet.client) if err != nil { - log.Fatalf("error initilaizing contract failed: %s", err.Error()) + logERC.Fatalf("error initilaizing contract failed: %s", err.Error()) } destinations := []common.Address{} @@ -1871,11 +1822,11 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa fromAddress := wallet.account.Address() nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } gasPrice, err := wallet.client.SuggestGasPrice(context.Background()) if err != nil { - log.Fatal(err) + logERC.Fatal(err) } auth := bind.NewKeyedTransactor(wallet.account.privateKey) @@ -1888,8 +1839,8 @@ func (wallet *ERC20Wallet) Multisign(ins []wi.TransactionInput, outs []wi.Transa tx, err = smtct.Execute(auth, vSlice, rSlice, sSlice, shash, destinations, amounts) - //fmt.Println(tx) - //fmt.Println(err) + //logERC.Info(tx) + //logERC.Info(err) if err != nil { return nil, err @@ -1981,9 +1932,9 @@ func (wallet *ERC20Wallet) CreateAddress() (common.Address, error) { fromAddress := wallet.account.Address() nonce, err := wallet.client.PendingNonceAt(context.Background(), fromAddress) if err != nil { - fmt.Println(err) + logERC.Info(err) } addr := crypto.CreateAddress(fromAddress, nonce) - //fmt.Println("Addr : ", addr.String()) + //logERC.Info("Addr : ", addr.String()) return addr, err } From 06256e90d557a2a1c61143834a8807e1089a1869 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Wed, 15 Apr 2020 01:58:00 +0530 Subject: [PATCH 6/7] merge master --- core/order.go | 15 +++++++++++ core/spend.go | 2 ++ qa/eth_complete_direct_online.py | 6 +++++ .../go-ethwallet/wallet/erc20_wallet.go | 27 +++++++++++++++++++ .../hunterlong/tokenbalance/tokenbalance.go | 2 +- wallet/listeners/transaction_listener.go | 23 ++++++++++------ 6 files changed, 66 insertions(+), 9 deletions(-) diff --git a/core/order.go b/core/order.go index 1dee49cc87..259bc065e8 100644 --- a/core/order.go +++ b/core/order.go @@ -137,24 +137,30 @@ func (n *OpenBazaarNode) Purchase(data *repo.PurchaseData) (orderID string, paym } // Add payment data and send to vendor if data.Moderator != "" { // Moderated payment + log.Info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") contract, err := prepareModeratedOrderContract(data, n, contract, wal) + log.Info("after prepareModeratedOrderContract, err: ", err) if err != nil { return "", "", retCurrency, false, err } contract, err = n.SignOrder(contract) + log.Info("after signorder : ", err) if err != nil { return "", "", retCurrency, false, err } // Send to order vendor merchantResponse, err := n.SendOrder(contract.VendorListings[0].VendorID.PeerID, contract) + log.Info("after send order, err : ", err) if err != nil { id, addr, amt, err := processOfflineModeratedOrder(n, contract) retCurrency.Amount = &amt return id, addr, retCurrency, false, err } + log.Info("ven dor is online ................") id, addr, amt, f, err := processOnlineModeratedOrder(merchantResponse, n, contract) + log.Info("after processOnlineModeratedOrder, err : ", err) retCurrency.Amount = &amt return id, addr, retCurrency, f, err @@ -470,14 +476,17 @@ func processOnlineModeratedOrder(resp *pb.Message, n *OpenBazaarNode, contract * } // Vendor responded if resp.MessageType == pb.Message_ERROR { + log.Info("ret 1111111111111111111111") return "", "", *big.NewInt(0), false, extractErrorMessage(resp) } if resp.MessageType != pb.Message_ORDER_CONFIRMATION { + log.Info("ret 2222222222222222222222") return "", "", *big.NewInt(0), false, errors.New("vendor responded to the order with an incorrect message type") } rc := new(pb.RicardianContract) err = proto.Unmarshal(resp.Payload.Value, rc) if err != nil { + log.Info("ret 33333333333333333333333 ", err) return "", "", *big.NewInt(0), false, errors.New("error parsing the vendor's response") } contract.VendorOrderConfirmation = rc.VendorOrderConfirmation @@ -487,24 +496,30 @@ func processOnlineModeratedOrder(resp *pb.Message, n *OpenBazaarNode, contract * } } err = n.ValidateOrderConfirmation(contract, true) + log.Info("ret 444444444444444444444444444 : ", err) if err != nil { return "", "", *big.NewInt(0), false, err } if contract.VendorOrderConfirmation.PaymentAddress != contract.BuyerOrder.Payment.Address { + log.Info("ret 555555555555555555555555555") return "", "", *big.NewInt(0), false, errors.New("vendor responded with incorrect multisig address") } orderID, err := n.CalcOrderID(contract.BuyerOrder) if err != nil { + log.Info("ret 6666666666666666666666666 : ", err) return "", "", *big.NewInt(0), false, err } err = n.Datastore.Purchases().Put(orderID, *contract, pb.OrderState_AWAITING_PAYMENT, false) if err != nil { + log.Info("ret 777777777777777777777777777 : ", err) return "", "", *big.NewInt(0), false, err } total, ok := new(big.Int).SetString(v5Order.Payment.BigAmount, 10) if !ok { + log.Info("ret 88888888888888888888888888") return "", "", *big.NewInt(0), false, errors.New("invalid payment amount") } + log.Info("ret last : ", orderID, " ", contract.VendorOrderConfirmation.PaymentAddress, " ", total.String()) return orderID, contract.VendorOrderConfirmation.PaymentAddress, *total, true, nil } diff --git a/core/spend.go b/core/spend.go index 7fe85f4edd..4101b5e999 100644 --- a/core/spend.go +++ b/core/spend.go @@ -101,6 +101,8 @@ func (n *OpenBazaarNode) Spend(args *SpendRequest) (*SpendResponse, error) { feeLevel = wallet.NORMAL } + log.Info("before wallet spend : amt - ", amt.String(), " addr : ", addr.String()) + log.Info("fee level : ", feeLevel, " orderID ", args.OrderID, " spend all ", args.SpendAll) txid, err := wal.Spend(*amt, addr, feeLevel, args.OrderID, args.SpendAll) if err != nil { switch { diff --git a/qa/eth_complete_direct_online.py b/qa/eth_complete_direct_online.py index 9c692a9753..8018a39670 100644 --- a/qa/eth_complete_direct_online.py +++ b/qa/eth_complete_direct_online.py @@ -19,9 +19,12 @@ def run_test(self): time.sleep(4) api_url = bob["gateway_url"] + "wallet/address/" + self.cointype r = requests.get(api_url) + print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") + print("bob api_url : ", api_url) if r.status_code == 200: resp = json.loads(r.text) address = resp["address"] + print(address) elif r.status_code == 404: raise TestFailure("EthCompleteDirectOnlineTest - FAIL: Address endpoint not found") else: @@ -55,11 +58,14 @@ def run_test(self): # get listing hash api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"] r = requests.get(api_url) + print("alice api_url : ", api_url) if r.status_code != 200: raise TestFailure("EthCompleteDirectOnlineTest - FAIL: Couldn't get listing index") resp = json.loads(r.text) listingId = resp[0]["hash"] + time.sleep(36000) + # bob send order with open('testdata/order_direct.json') as order_file: order_json = json.load(order_file, object_pairs_hook=OrderedDict) diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index 09864d0e3a..ae809cff32 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -228,6 +228,7 @@ func (wallet *ERC20Wallet) Start() { doneBalanceTickerERC20 = make(chan bool) // start the ticker to check for pending txn rcpts go func(wallet *ERC20Wallet) { + logERC.Info("txn check ticker .....") ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() @@ -236,12 +237,15 @@ func (wallet *ERC20Wallet) Start() { case <-done: return case <-ticker.C: + logERC.Info("tick tick .....") // get the pending txns txns, err := wallet.db.Txns().GetAll(true) + logERC.Info("do we have txns .... ", txns, " ", err) if err != nil { continue } for _, txn := range txns { + logERC.Info("lets qqqqqqqqqqqq ", txn.Txid) hash := common.HexToHash(txn.Txid) go func(txnData []byte) { _, err := wallet.checkTxnRcpt(&hash, txnData) @@ -576,6 +580,7 @@ func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { // WatchOnly: false, // Bytes: tx.Data(), // }, nil + logERC.Info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") tx, _, err := wallet.client.GetTransaction(common.HexToHash(util.EnsureCorrectPrefix(txid.String()))) if err != nil { return wi.Txn{}, err @@ -591,12 +596,16 @@ func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { return wi.Txn{}, err } + logERC.Info("AAAAAAAAAa111111111111") + //value := tx.Value().String() fromAddr := msg.From() toAddr := msg.To() valueSub := big.NewInt(5000000) value := tx.Value() + logERC.Info(hexutil.Encode(msg.Data())) + if strings.HasPrefix(hexutil.Encode(msg.Data()), "0xa9059cbb") { value = big.NewInt(0).SetBytes(msg.Data()[36:]) } else if strings.HasPrefix(hexutil.Encode(msg.Data()), "0x57bced76") { @@ -605,6 +614,8 @@ func (wallet *ERC20Wallet) GetTransaction(txid chainhash.Hash) (wi.Txn, error) { valueSub = value } + logERC.Info(value.String()) + if tx.To().String() == wallet.currentdeployAddress.String() { toAddr = wallet.address.address valueSub = value @@ -681,6 +692,7 @@ func (wallet *ERC20Wallet) GetFeePerByte(feeLevel wi.FeeLevel) big.Int { // Spend - Send ether to an external wallet func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel wi.FeeLevel, referenceID string, spendAll bool) (*chainhash.Hash, error) { + logERC.Info(",,, in erc20 spend ..... ", amount.String(), " ", addr.String(), referenceID) var hash common.Hash var h *chainhash.Hash var err error @@ -703,6 +715,7 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel key := addrEth.Bytes() redeemScript := []byte{} + logERC.Info("if this a moderated or disputed order, then it is a script address .... ") for _, script := range scripts { if bytes.Equal(key, script[:common.AddressLength]) { isScript = true @@ -711,6 +724,8 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel } } + logERC.Info("is this a script : ", isScript) + if isScript { ethScript, err := DeserializeEthScript(redeemScript) if err != nil { @@ -721,6 +736,7 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel logERC.Error(err.Error()) } addrScrHash := common.HexToAddress(scrHash) + logERC.Info("addrScrHash : ", addrScrHash.String()) actualRecipient = EthAddress{address: &addrScrHash} //EthAddress{address: ðScript.Seller} //EthAddress{address: &addrScrHash} hash, _, err = wallet.callAddTokenTransaction(ethScript, &amount, feeLevel) if err != nil { @@ -737,8 +753,10 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel return nil, err } + logERC.Info("we have the hash here : ", hash.String()) // txn is pending nonce, err := wallet.client.GetTxnNonce(util.EnsureCorrectPrefix(hash.Hex())) + logERC.Info("after get nonce ", nonce, " ", err) if err == nil { data, err := SerializePendingTxn(PendingTxn{ TxnID: hash, @@ -758,12 +776,15 @@ func (wallet *ERC20Wallet) Spend(amount big.Int, addr btcutil.Address, feeLevel } } + logERC.Info("almost near ... ", err) + if err == nil { h, err = util.CreateChainHash(hash.Hex()) if err == nil { wallet.invokeTxnCB(h.String(), &amount) } } + logERC.Info("before return : ", h, " ", err) return h, err } @@ -915,23 +936,28 @@ func (wallet *ERC20Wallet) AssociateTransactionWithOrder(txnCB wi.TransactionCal // checkTxnRcpt check the txn rcpt status func (wallet *ERC20Wallet) checkTxnRcpt(hash *common.Hash, data []byte) (*common.Hash, error) { + logERC.Info("in chk txn rcpt .... ", hash.String()) var rcpt *types.Receipt pTxn, err := DeserializePendingTxn(data) + logERC.Info("after deserializing data : ", err) if err != nil { return nil, err } rcpt, err = wallet.client.TransactionReceipt(context.Background(), *hash) + logERC.Info("after TransactionReceipt ", rcpt, " ", err) if err != nil { logERC.Infof("fetching txn rcpt: %v", err) } if rcpt != nil { + logERC.Info("rcpt is not nil .... status : ", rcpt.Status) // good. so the txn has been processed but we have to account for failed // but valid txn like some contract condition causing revert if rcpt.Status > 0 { // all good to update order state chash, err := util.CreateChainHash((*hash).Hex()) + logERC.Info("after create chain hash : ", chash.String(), " ", err) if err != nil { return nil, err } @@ -939,6 +965,7 @@ func (wallet *ERC20Wallet) checkTxnRcpt(hash *common.Hash, data []byte) (*common if err != nil { logERC.Errorf("err deleting the pending txn : %v", err) } + logERC.Info("amount : ", pTxn.Amount) n := new(big.Int) n, _ = n.SetString(pTxn.Amount, 10) toAddr := common.HexToAddress(pTxn.To) diff --git a/vendor/github.com/hunterlong/tokenbalance/tokenbalance.go b/vendor/github.com/hunterlong/tokenbalance/tokenbalance.go index 50b617527c..df21e240e0 100644 --- a/vendor/github.com/hunterlong/tokenbalance/tokenbalance.go +++ b/vendor/github.com/hunterlong/tokenbalance/tokenbalance.go @@ -60,7 +60,7 @@ func (c *Config) Connect() error { } config = c Geth = ethConn - log(fmt.Sprintf("Connected to Geth at: %v\n", c.GethLocation), false) + //log(fmt.Sprintf("Connected to Geth at: %v\n", c.GethLocation), false) return err } diff --git a/wallet/listeners/transaction_listener.go b/wallet/listeners/transaction_listener.go index 86a3dbd7b9..51a6e11a8b 100644 --- a/wallet/listeners/transaction_listener.go +++ b/wallet/listeners/transaction_listener.go @@ -55,11 +55,13 @@ func (l *TransactionListener) getOrderDetails(orderID string, address btc.Addres return contract, state, funded, records, err } +// OnTransactionReceived - the beating heart of ob-go order processing func (l *TransactionListener) OnTransactionReceived(cb wallet.TransactionCallback) { log.Info("Transaction received", cb.Txid, cb.Height) l.Lock() defer l.Unlock() + log.Info("txn outputs: ", cb.Outputs) for _, output := range cb.Outputs { if output.Address == nil { continue @@ -78,6 +80,7 @@ func (l *TransactionListener) OnTransactionReceived(cb wallet.TransactionCallbac continue } contract, state, funded, records, err = l.getOrderDetails(output.OrderID, output.Address, false) + log.Info("lets see if this is a a purchase ...", err == nil) if err == nil { l.processPurchasePayment(cb.Txid, output, contract, state, funded, records) continue @@ -315,7 +318,9 @@ func (l *TransactionListener) processSalePayment(txid string, output wallet.Tran } func (l *TransactionListener) processPurchasePayment(txid string, output wallet.TransactionOutput, contract *pb.RicardianContract, state pb.OrderState, funded bool, records []*wallet.TransactionRecord) { + log.Info("in process purchase ") funding := output.Value + log.Info("111 funding : ", funding.String(), " funded : ", funded) for _, r := range records { funding = *new(big.Int).Add(&funding, &r.Value) // If we have already seen this transaction for some reason, just return @@ -323,7 +328,9 @@ func (l *TransactionListener) processPurchasePayment(txid string, output wallet. return } } - orderId, err := calcOrderId(contract.BuyerOrder) + log.Info("222 funding : ", funding.String()) + orderID, err := calcOrderId(contract.BuyerOrder) + log.Info("after caclorder id, err : ", err) if err != nil { return } @@ -335,15 +342,15 @@ func (l *TransactionListener) processPurchasePayment(txid string, output wallet. if !funded { requestedAmount, _ := new(big.Int).SetString(order.Payment.BigAmount, 10) if funding.Cmp(requestedAmount) >= 0 { - log.Debugf("Payment for purchase %s detected", orderId) + log.Debugf("Payment for purchase %s detected", orderID) funded = true if state == pb.OrderState_AWAITING_PAYMENT && contract.VendorOrderConfirmation != nil { // Confirmed orders go to AWAITING_FULFILLMENT - if err := l.db.Purchases().Put(orderId, *contract, pb.OrderState_AWAITING_FULFILLMENT, false); err != nil { - log.Errorf("failed updating order (%s) to AWAITING_FULFILLMENT: %s", orderId, err.Error()) + if err := l.db.Purchases().Put(orderID, *contract, pb.OrderState_AWAITING_FULFILLMENT, false); err != nil { + log.Errorf("failed updating order (%s) to AWAITING_FULFILLMENT: %s", orderID, err.Error()) } } else if state == pb.OrderState_AWAITING_PAYMENT && contract.VendorOrderConfirmation == nil { // Unconfirmed go into PENDING - if err := l.db.Purchases().Put(orderId, *contract, pb.OrderState_PENDING, false); err != nil { - log.Errorf("failed updating order (%s) to PENDING: %s", orderId, err.Error()) + if err := l.db.Purchases().Put(orderID, *contract, pb.OrderState_PENDING, false); err != nil { + log.Errorf("failed updating order (%s) to PENDING: %s", orderID, err.Error()) } } } @@ -360,7 +367,7 @@ func (l *TransactionListener) processPurchasePayment(txid string, output wallet. n := repo.PaymentNotification{ ID: repo.NewNotificationID(), Type: "payment", - OrderId: orderId, + OrderId: orderID, FundingTotal: cv, CoinType: order.Payment.AmountCurrency.Code, } @@ -379,7 +386,7 @@ func (l *TransactionListener) processPurchasePayment(txid string, output wallet. Timestamp: time.Now(), } records = append(records, record) - err = l.db.Purchases().UpdateFunding(orderId, funded, records) + err = l.db.Purchases().UpdateFunding(orderID, funded, records) if err != nil { log.Error(err) } From b0835f8d44664d6795de40ea774f7b9bd873ac12 Mon Sep 17 00:00:00 2001 From: Ashwin Mangale Date: Wed, 15 Apr 2020 03:33:06 +0530 Subject: [PATCH 7/7] fetch token transactions --- .../OpenBazaar/go-ethwallet/wallet/erc20_wallet.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go index ae809cff32..6baa475310 100644 --- a/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go +++ b/vendor/github.com/OpenBazaar/go-ethwallet/wallet/erc20_wallet.go @@ -494,7 +494,11 @@ func (wallet *ERC20Wallet) Balance() (confirmed, unconfirmed int64) { // TransactionsFromBlock - Returns a list of transactions for this wallet begining from the specified block func (wallet *ERC20Wallet) TransactionsFromBlock(startBlock *int) ([]wi.Txn, error) { - txns, err := wallet.client.eClient.NormalTxByAddress(util.EnsureCorrectPrefix(wallet.account.Address().String()), startBlock, nil, + // txns, err := wallet.client.eClient.NormalTxByAddress(util.EnsureCorrectPrefix(wallet.account.Address().String()), startBlock, nil, + // 1, 0, false) + contractAddress := wallet.currentdeployAddress.String() + accountAddress := util.EnsureCorrectPrefix(wallet.account.Address().String()) + txns, err := wallet.client.eClient.ERC20Transfers(&contractAddress, &accountAddress, startBlock, nil, 1, 0, false) if err != nil { logERC.Error("err fetching transactions : ", err) @@ -505,9 +509,6 @@ func (wallet *ERC20Wallet) TransactionsFromBlock(startBlock *int) ([]wi.Txn, err for _, t := range txns { status := wi.StatusConfirmed prefix := "" - if t.IsError != 0 { - status = wi.StatusError - } if strings.ToLower(t.From) == strings.ToLower(wallet.address.String()) { prefix = "-" }