ethereum docker geth shell for geth attach and tail log

Help use docker geth for geth attach and watch log. Geth Command line path need to change for yourself env. #!/bin/sh IFS=$'\n' echo $1 echo $2 case $2 in attach) docker exec -it $(docker ps -a --no-trunc | grep $1 | awk '{print $1}') geth attach --datadir=/root/.ethereum/devchain ;; log) docker exec -it $(docker ps -a --no-trunc | grep $1 | awk '{print $1}') tail -n 30 -f /root/geth.log ;; sh) docker exec -it $(docker ps -a --no-trunc | grep $1 | awk '{print $1}') sh ;; bash) docker exec -it $(docker ps -a --no-trunc | grep $1 | awk '{print $1}') bash ;; *) echo "command parms1: docker container name" echo "command parms2: attach (geth attach) or log (tail -n 30 -f) or sh or bash" esac

2020-01-10 · 1 min · 127 words · Me

How to test your self ethereum geth private poa truffle part2

every sec send transaction nonce++ https://medium.com/finnovate-io/how-do-i-sign-transactions-with-web3-f90a853904a2 https://ethereum.stackexchange.com/questions/60611/defining-the-transaction-object-for-offline-transaction-signing-using-web3-js-f https://github.com/ethereum/web3.js/issues/1430 https://programtheblockchain.com/posts/ signTransaction(tx, “0x”+privateKey) “0x” privatekey need becarful. --ws --wsaddr 0.0.0.0 --wsorigins "*" --wsapi "db,admin,debug,miner,eth,net,web3,network,txpool" var fs = require('fs'); var Web3 = require("web3"); var provider = new Web3.providers.HttpProvider("http://192.168.99.100:18545"); var wsprovider = new Web3.providers.WebsocketProvider("ws://192.168.99.100:18546"); //var web3 = new Web3(provider); var web3 = new Web3(wsprovider); console.log("before web set account: %o", web3.eth.defaultAccount); const privateKey = '138cbbfb21686ddc3b5ffeb2cfc83491175af68319977acb81d0ae93392c626c'; const account = web3.eth.accounts.privateKeyToAccount('0x' + privateKey); //web3.eth.accounts.wallet.add(account); //console.log("private key import to account: %o", account.address) web3.eth.defaultAccount = account.address; // try { // web3.eth.personal.unlockAccount(account.address, "").then(console.log('Account unlocked!')); // } catch (err) { // console.error('web3 unlockAccount Error: %o', err); // } var certjson; var certjsonpath = './Cert.json'; try { certjson = JSON.parse(fs.readFileSync(certjsonpath)); } catch (err) { console.error('readFileSync Error: %o', err); } var contractjson; var contractjsonpath = './MetaCoin.json'; try { contractjson = JSON.parse(fs.readFileSync(contractjsonpath)); } catch (err) { console.error('readFileSync Error: %o', err); } const getNonce = () => { return new Promise((resolve, reject) => { web3.eth.getTransactionCount(web3.eth.defaultAccount, 'pending', (error, result) => { if(error) reject(error); resolve(web3.utils.toHex(result)); }) }) } const getGasPrice = () => { return new Promise((resolve, reject) => { web3.eth.getGasPrice((error, result) => { if(error) reject(error); resolve(web3.utils.toHex(result)); }) }) } const createContract = (contractfrom_caller, nonce="") => { return new Promise((resolve, reject) => { const tx = { from: contractfrom_caller, gasPrice: web3.utils.toHex(web3.utils.toWei('2', 'gwei')), //20,000,000,000 gas: web3.utils.toHex('6819490'), //gasLimit: 9000000, value: '0x00', // web3.utils.toHex('0'), data: certjson.bytecode }; if(nonce!="") { tx.nonce = nonce; console.log("tx: %o", tx); } // const keystore = "Contents of keystore file"; // const decryptedAccount = web3.eth.accounts.decrypt(keystore, 'PASSWORD'); // web3.eth.accounts.signTransaction(rawTransaction, decryptedAccount.privateKey) // .then(console.log); // OR // decryptedAccount.signTransaction(tx) //const signPromise = web3.eth.accounts.signTransaction(tx, "0x"+privateKey); web3.eth.accounts.signTransaction(tx, "0x"+privateKey) .then(resolve) .catch(reject); }) } const getBalance = (contractAddr, coinOwnerAddr) => { return new Promise((resolve, reject) => { web3.eth.call({ to: contractAddr, data: metaCoinContract.methods.getBalance(coinOwnerAddr).encodeABI() }) .then(resolve) .catch(reject); // .then(o => { // resolve(o); // }) // .catch((error) => { // reject(error) // }); }) } const sendCoin = (contractAddr, sendCointoAddr, coinNumber, nonce="") => { return new Promise((resolve, reject) => { const tx = { from: contractfrom_caller, to: contractAddr, gasPrice: web3.utils.toHex(web3.utils.toWei('2', 'gwei')), //20,000,000,000 gas: web3.utils.toHex('181949'), //gasLimit: 9000000, value: '0x00', // web3.utils.toHex('0'), data: metaCoinContract.methods.sendCoin(sendCointoAddr, coinNumber).encodeABI() }; if(nonce!="") { tx.nonce = nonce; console.log("tx: %o", tx); } // const keystore = "Contents of keystore file"; // const decryptedAccount = web3.eth.accounts.decrypt(keystore, 'PASSWORD'); // web3.eth.accounts.signTransaction(rawTransaction, decryptedAccount.privateKey) // .then(console.log); // OR // decryptedAccount.signTransaction(tx) //const signPromise = web3.eth.accounts.signTransaction(tx, "0x"+privateKey); web3.eth.accounts.signTransaction(tx, "0x"+privateKey) .then(resolve) .catch(reject); }) } contractAddr = "0x3Da963B807bF892F7A10B61E9ffD830068f8C23d"; contractfrom_caller = "0xe79d33e93bd888b35e055f1a12d876354729037b"; coinOwnerAddr = "0xe79d33e93bd888b35e055f1a12d876354729037b" sendCointoAddr = "0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176"; const metaCoinContract = new web3.eth.Contract(contractjson.abi, contractAddr); // getBalance // web3.eth.call({ // to: contractAddr, // data: metaCoinContract.methods.getBalance(coinOwnerAddr).encodeABI() // }) // .then(o => { // console.log("%s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) // }); getBalance(contractAddr, coinOwnerAddr) .then(o => { console.log("%s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) }) .catch((error) => { console.log("getBalance catch error: %o", error.message); }); // transfor coin // const signPromise = sendCoin(contractAddr, sendCointoAddr, 10); // signPromise.then((signedTx) => { // const sentTx = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction); // sentTx.on("receipt", receipt => { // console.log("receipt: %o", receipt); // console.log("receipt.contractAddress: %o", receipt.contractAddress); // }); // sentTx.on("error", error => { // console.log("sendSignedTransaction error: %o", error.message); // }) // sentTx.then(o => { // TxHash = o.transactionHash; // console.log("##### TxHash: %o", TxHash) // }); // }).catch((error) => { // console.log("sendSignedTransaction catch error: %o", error.message); // }); // getBalance coin sender & reciver getBalance(contractAddr, coinOwnerAddr) .then(o => { console.log("coinOwnerAddr %s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) }) .catch((error) => { console.log("getBalance catch error: %o", error.message); }); getBalance(contractAddr, sendCointoAddr) .then(o => { console.log("sendCointoAddr %s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) }) .catch((error) => { console.log("getBalance catch error: %o", error.message); }); Promise.all([getNonce(), getGasPrice()]).then(values => { var nonce = web3.utils.hexToNumberString(values[0]); console.log("Nonce: %o", nonce); createContract(contractAddr, web3.utils.toHex(nonce)).then((signedTx) => { console.log('createContract signedTx: %o', signedTx); const sentTx = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction); sentTx.then(o => { TxHash = o.transactionHash; console.log("##### createContract TxHash: %o", TxHash); web3.eth.getTransactionReceipt(TxHash).then(o=>{ console.log("check contractAddress object: %s", o.contractAddress); }); }) .catch((error) => { console.log("createContract sendSignedTransaction catch error: %o", error.message); }); }).catch((error) => { console.log("screateContract catch error: %o", error.message); }); nonce++; setInterval( () => { sendCoin(contractAddr, sendCointoAddr, 10, web3.utils.toHex(nonce)).then((signedTx) => { console.log('sendCoin 3 signedTx: %o', signedTx); const sentTx3 = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction); sentTx3.then(o => { TxHash = o.transactionHash; console.log("##### sendCoin 3 TxHash: %o", TxHash); }) .catch((error) => { console.log("sendCoin 3 catch error: %o", error.message); }); }).catch((error) => { console.log("sendSignedTransaction3 catch error: %o", error.message); }); nonce++; console.log("Nonce: %o", nonce); getBalance(contractAddr, coinOwnerAddr) .then(o => { console.log("coinOwnerAddr %s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) }) .catch((error) => { console.log("getBalance catch error: %o", error.message); }); getBalance(contractAddr, sendCointoAddr) .then(o => { console.log("sendCointoAddr %s getBalance at %s contract: %o", coinOwnerAddr, contractAddr, web3.utils.hexToNumberString(o)) }) .catch((error) => { console.log("getBalance catch error: %o", error.message); }); }, Math.random() * 1000); }) .then(console.log("Promise all transaction ok!")) .catch(e => console.log("promise all error: %o", e.message)) // sendCoin(contractAddr, sendCointoAddr, 10).then((signedTx) => { // console.log('sendCoin 2 signedTx: %o', signedTx); // const sentTx2 = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction); // sentTx2.then(o => { // TxHash = o.transactionHash; // console.log("##### sendCoin 2 TxHash: %o", TxHash) // }) // .catch((error) => { console.log("sendCoin 2 catch error: %o", error.message); }); // }).catch((error) => { console.log("sendSignedTransaction2 catch error: %o", error.message); }); // sendCoin(contractAddr, sendCointoAddr, 10).then((signedTx) => { // console.log('sendCoin 3 signedTx: %o', signedTx); // const sentTx3 = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction); // sentTx3.then(o => { // TxHash = o.transactionHash; // console.log("##### sendCoin 3 TxHash: %o", TxHash) // }) // .catch((error) => { console.log("sendCoin 3 catch error: %o", error.message); }); // }).catch((error) => { console.log("sendSignedTransaction3 catch error: %o", error.message); }); //metaCoinContract.events.allEvents() metaCoinContract.events.Transfer() .on('data', function(event){ console.log("##### events data: %o", event); // same results as the optional callback above }) .on('changed', function(event){ console.log("##### events changed: %o", event); }) .on('error', console.error); metaCoinContract.getPastEvents('Transfer', function(error, events){ console.log("##### getPastEvents changed: %o", events); }) .then(function(events){ console.log("##### getPastEvents changed: %o", events) // same results as the optional callback above });

2020-01-02 · 5 min · 935 words · Me

[轉]解決replacement transaction underpriced以太坊交易異常

https://www.twblogs.net/a/5bb2596a2b71770e645ddc3c replacement transaction underpriced異常 問題概述 以太坊系列(ETH&ETC)在發送交易有三個對應的RPC接口,分別是ethsendTransaction、ethsendRawTransaction和personal_sendTransaction。這三個接口發送(或構造發送內容時)都需要一個參數nonce。官方文檔對此參數的解釋是:整數類型,允許使用相同隨機數覆蓋自己發送的處於pending狀態的交易。 僅從官網的解釋,我們無法獲取到更多的有效的信息。但在真實生成中我們會發現如果傳錯nonce字段值,通過RPC接口調用發送的交易很大可能將不會被確認。如果通過console命令來操作一般不會出現此問題,因爲節點已經幫我們處理了。 如果繼續追蹤問題,會發現nonce傳遞錯誤的交易可以通過eth_getTransaction查詢得到相關信息,但是它的blocknumber始終未null,也就說這邊交易始終未被確認。如果是在dev模式下,應該是很快就會被確認的。更進一步,通過txpool.content命令,會發現那筆交易一直處於queued隊列中,而未被消費。 在使用同一個地址連續發送交易時,每筆交易往往不可能立即到賬, 當前交易還未到賬的情況下,下一筆交易無論是通過eth.getTransactionCount()獲取nonce值來設置,還是由節點自動從區塊中查詢,都會獲得和前一筆交易同樣的nonce值,這時節點就會報錯Error: replacement transaction underpriced 爲了防止交易重播,ETH(ETC)節點要求每筆交易必須有一個nonce數值。每一個賬戶從同一個節點發起交易時,這個nonce值從0開始計數,發送一筆nonce對應加1。當前面的nonce處理完成之後纔會處理後面的nonce。注意這裏的前提條件是相同的地址在相同的節點發送交易。 以下是nonce使用的幾條規則: ● 當nonce太小(小於之前已經有交易使用的nonce值),交易會被直接拒絕。 ● 當nonce太大,交易會一直處於隊列之中,這也就是導致我們上面描述的問題的原因; ● 當發送一個比較大的nonce值,然後補齊開始nonce到那個值之間的nonce,那麼交易依舊可以被執行。 ● 當交易處於queue中時停止geth客戶端,那麼交易queue中的交易會被清除掉。 如果系統中的熱點賬戶或普通賬戶發起交易時出現error: replacement transaction underpriced異常,那麼就需要考慮nonce使用是否正確。 引起此異常原因主要是當一個賬戶發起一筆交易,假設使用nonce爲1,交易已經發送至節點中,但由於手續費不高或網絡擁堵或nonce值過高,此交易處於queued中遲遲未被打包。 同時此地址再發起一筆交易,如果通過eth_getTransactionCount獲取的nonce值與上一個nonce值相同,用同樣的nonce值再發出交易時,如果手續費高於原來的交易,那麼第一筆交易將會被覆蓋,如果手續費低於原來的交易就會發生上面的異常。 通常發生此異常意味着: - 你的Ethereum客戶端中已經有一筆處於pending狀態的交易。 - 新的一筆交易擁有pending狀態交易相同的nonce值。 - 新的交易的gas price太小,無法覆蓋pending狀態的交易。 通常情況下,覆蓋掉一筆處於pending狀態的交易gas price需要高於原交易的110%。 經過上面的解釋追蹤,我們已經瞭解到了nonce的基本使用規則。那麼,在實際應該用中我們如何保障nonce值的可靠性呢?這裏有兩個思路, 第一個思路就是由業務系統維護nonce值的遞增。如果交易發送就出現問題,那麼該地址下一筆交易繼續使用這個nonce進行發送交易。 第二個思路就是使用現有的api查詢當前地址已經發送交易的nonce值,然後對其加1,再發送交易。對應的API接口爲:eth_getTransactionCount,此方法由兩個參數,第一個參數爲需要查詢nonce的地址,第二個參數爲block的狀態:latest、earliest和pending。一般情況使用pending就可以查詢獲得最新已使用的nonce。其他狀態大家可以自行驗證。 第三個思路就 如果該熱點賬戶的私鑰信息等都存放在Ethereum客戶端中,那麼在發送交易的時候不傳遞nonce值,Ethereum客戶端會幫你處理好此nonce值的排序。 當然,此方案有兩個弊端。第一個是安全性無法保障(未進行冷熱賬戶分離),第二,在熱點賬戶下如果想覆蓋掉一筆交易,需要先查詢一下該交易的信息,從中獲取nonce值。 第一個思路 自行管理nonce適用於冷熱賬戶模式,也就是適用sendRawTransaction發送已經簽名好的交易時,此時nonce值已經存在於交易中,並且已經被簽名。 這種模式下,需要在業務系統中維護nonce的自增序列,使用一個nonce之後,在業務系統中對nonce進行加一處理。 此種方案也有限制條件。第一,由於nonce統一進行維護,那麼這個地址必須是內部地址,而且發起交易必須通過統一維護的nonce作爲出口,否則在其他地方發起交易,原有維護的nonce將會出現混亂。第二,一旦已經發出的交易發生異常,異常交易的nonce未被使用,那麼異常交易的nonce需要重新被使用之後它後面的nonce纔會生效。 在構建一筆新的交易時,在交易數據結構中會產生一個nonce值, nonce是當前區塊鏈下,發送者(from地址)發出的交易(成功記錄進區塊的)總數, 再加上1。例如新構建一筆從A發往B的交易,A地址之前的交易次數爲10,那麼這筆交易中的nonce則會設置成11, 節點驗證通過後則會放入交易池(txPool),並向其他節點廣播,該筆交易等待礦工將其打包進新的區塊。 第二個思路 那麼,如果在先構建併發送了一筆從地址A發出的,nonce爲11的交易,在該交易未打包進區塊之前, 再次構建一筆從A發出的交易,並將它發送到節點,不管是先通過web3的eth.getTransactionCount(A)獲取到的過往的交易數量,還是由節點自行填寫nonce, 後面的這筆交易的nonce同樣是11, 此時就出現了問題: 後面的這筆交易手續費給得更高, 那麼節點會前面的那筆交易從交易池中剔除,轉而放入後面構建的這筆交易 如果後面的這筆交易給得不夠高, 就會被廢棄掉, 如果通過web3這樣的sdk來向節點發送交易時,會收到錯誤信息 實際場景中 ,會有批量從一個地址發送交易的需求,首先這些操作可能也應該是並行的,我們不會等待一筆交易成功寫入區塊後再發起第二筆交易,那麼此時有什麼好的解決辦法呢?先來看看geth節點中交易池對交易的處理流程 如之前所說, 第三個思路 構建一筆交易時如果不手動設置nonce值,geth節點會默認計算發起地址此前最大nonce數(寫入區塊的才算數),然後將其加上1, 然後將這筆交易放入節點交易池中的pending隊列,等到節點將其打包進區塊。 第一個思路 構建交易時,nonce值是可以手動設置的,如果當前的nonce本應該設置成11, 但是我手動設置成了13, 在節點收到這筆交易時, 發現pending隊列中並沒有改地址下nonce爲11及12的交易, 就會將這筆nonce爲13的交易放入交易池的queued隊列中。只有當前面的nonce補齊(nonce爲11及12的交易被發現並放入pending隊列)之後,纔會將它放入pending隊列中等待打包。 ...

2019-12-26 · 1 min · 102 words · Me

How to test your self ethereum geth private poa truffle

Important!! web3.eth.sendTransaction({ data: bytecode “certjson.bytecode” or “certjson.bytecode.object” MUST Have “0x” at line First Character Use Truffle 1. run https://www.trufflesuite.com/docs/truffle/quickstart 1-1. run command mkdir testtruffle cd testtruffle npm i web3 truffle unbox metacoin truffle test ./test/TestMetaCoin.sol truffle test ./test/metacoin.js truffle compile 2. modify truffle-config.js Here use your private poa chain networkinfo. from address must be can used. genesis file can put this address. module.exports = { // Uncommenting the defaults below // provides for an easier quick-start with Ganache. // You can also follow this format for other networks; // see // for more details on how to specify configuration options! // networks: { development: { host: "192.168.99.100", port: 8545, network_id: "*", from: "0x5921a4c1b13afbd4b61d63e9c7bd47741c47b176" }, // test: { // host: "127.0.0.1", // port: 7545, // network_id: "*" // } } }; 3. modify migrations/1_initial_migration.js ...

2019-12-26 · 8 min · 1511 words · Me

metamask Web3 ProviderEngine

https://github.com/MetaMask/web3-provider-engine

2019-12-24 · 1 min · word · Me