EExcel 丞燕快速查詢2

EExcel 丞燕快速查詢2
EExcel 丞燕快速查詢2 https://sandk.ffbizs.com/

修行

你從那裡來? 妄想從那裡來?

心自體不可得,作用可得

開顯自己的真如本性
修行從裡面(內在)生起,這個心誰都不能破壞

印光大師說:全世界的人念佛都沒有感應,全世界的人念佛都沒求生淨土,我照樣念佛,我照樣求生淨土

跟外境沒有關係

不生滅心

https://youtu.be/iudlojChsKs?list=PLA16E144975D1AFCD&t=1963



修正自己的行為

[轉]解決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隊列中等待打包。

我們把pending隊列中的交易視爲可執行的,因爲它們可能被礦工打包進最新的區塊。 而queue隊列因爲前面的nonce存在缺失,暫時無法被礦工打包,稱爲不可執行交易。

那麼

實際開發中
,批量從一個地址發送交易時,應該怎麼辦呢?


方案一:

那麼在批量從一個地址發送交易時, 可以持久化一個本地的nonce,構建交易時用本地的nonce去累加,逐一填充到後面的交易。(要注意本地的nonce可能會出現偏差,可能需要定期從區塊中重新獲取nonce,更新至本地)。這個方法也有一定的侷限性,適合內部地址(即只有這個服務會使用該地址發送交易)。

說到

這裏還有個坑

,許多人認爲通過eth.getTransactionCount(address, "pending"),第二個參數爲pending, 就能獲得包含本地交易池pending隊列的nonce值,但是實際情況並不是這樣, 這裏的pending只包含待放入打包區塊的交易, 假設已寫入交易區塊的數量爲20, 又發送了nonce爲21,22,23的交易, 通過上面方法取得nonce可能是21(前面的21,22,23均未放入待打包區塊), 也可能是22(前面的21放入待打包區塊了,但是22,23還未放入)。

新版本的Geth好像解決了這個問題,在超大量測試transaction中,沒發現上述情況,如這問題還在應該會是大量錯誤一直產生才對!

超大量測試transaction

方案二:

是每次構建交易時,從geth節點的pending隊列取到最後一筆可執行交易的nonce, 在此基礎上加1,再發送給節點。可以通過txpool.content或txpool.inspect來獲得交易池列表,裏面可以看到pending及queue的交易列表。

其他方式:

啓動節點時,是可以設置交易池中的每個地址的pending隊列的容量上限,queue隊列的上容量上限, 以及整個交易池的pending隊列和queue隊列的容量上限。所以高併發的批量交易中,需要增加節點的交易池容量。

當然,除了擴大交易池,控制發送頻率,更要設置合理的交易手續費,eth上交易寫入區塊的速度取決於手續費及eth網絡的擁堵狀況,發送每筆交易時,設置合理的礦工費用,避免大量的交易積壓在交易池。

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

If account have password, remark some line to put password. Here example no password.

Import: importRawKey maybe run one time, get error msg "Error: Returned error: account already exists" then remark.


Import: if unlock failed, may be is geth new version need to add --allow-insecure-unlock



const Web3 = require('web3');
const TruffleConfig = require('../truffle-config.js');

const Migrations = artifacts.require("Migrations");

module.exports = function(deployer) {
  const config = TruffleConfig.networks.development;

  //if (process.env.ACCOUNT_PASSWORD) {
    const web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.host + ':' + config.port));

    // maybe only run one time for geth
    // web3.eth.personal.importRawKey('d05bd152f3d71ff5f91830f3ccc1090fb670c7026ebf8c2136d4e5090d59398d', '')
    // web3.eth.personal.importRawKey('138cbbfb21686ddc3b5ffeb2cfc83491175af68319977acb81d0ae93392c626c', '')

    // if unlock failed, may be is geth new version need to add --allow-insecure-unlock 
    console.log('>> Unlocking account ' + config.from);
    // //web3.personal.unlockAccount(config.from, process.env.ACCOUNT_PASSWORD, 36000);
    web3.eth.personal.unlockAccount(config.from, '', 36000);
  //}

  console.log('>> Deploying migration');

  deployer.deploy(Migrations);
};


truffle migrate


4. run

truffle test

Why you need to do this, because you can run many test (open 3 or more command line run truffle test) on same time for test your private poa ethereum.

If see Error, next step.


5. modify test/metacoin.js check code like this:


const MetaCoin = artifacts.require("MetaCoin");

Check accounts who have coin then change balance 0 or 1 & account one or two.

contract('MetaCoin', (accounts) => {
  it('should put 10000 MetaCoin in the first account', async () => {
    const metaCoinInstance = await MetaCoin.deployed();
    console.log('\n accounts: %o\n', accounts);
    
    const balance0 = await metaCoinInstance.getBalance.call(accounts[0]);
    const balance1 = await metaCoinInstance.getBalance.call(accounts[1]);
    console.log('balance0: %s', balance0.valueOf());
    console.log('balance1: %s\n', balance1.valueOf());

    assert.equal(balance1.valueOf(), 10000, "10000 wasn't in the first account");
  });
  it('should call a function that depends on a linked library', async () => {
    const metaCoinInstance = await MetaCoin.deployed();
    const metaCoinBalance = (await metaCoinInstance.getBalance.call(accounts[0])).toNumber();
    const metaCoinEthBalance = (await metaCoinInstance.getBalanceInEth.call(accounts[0])).toNumber();

    assert.equal(metaCoinEthBalance, 2 * metaCoinBalance, 'Library function returned unexpected function, linkage may be broken');
  });
  it('should send coin correctly', async () => {
    const metaCoinInstance = await MetaCoin.deployed();

    // Setup 2 accounts.
    const accountOne = accounts[1];
    const accountTwo = accounts[0];

    // Get initial balances of first and second account.
    const accountOneStartingBalance = (await metaCoinInstance.getBalance.call(accountOne)).toNumber();
    const accountTwoStartingBalance = (await metaCoinInstance.getBalance.call(accountTwo)).toNumber();

    // Make transaction from first account to second.
    const amount = 10;
    await metaCoinInstance.sendCoin(accountTwo, amount, { from: accountOne });

    // Get balances of first and second account after the transactions.
    const accountOneEndingBalance = (await metaCoinInstance.getBalance.call(accountOne)).toNumber();
    const accountTwoEndingBalance = (await metaCoinInstance.getBalance.call(accountTwo)).toNumber();


    assert.equal(accountOneEndingBalance, accountOneStartingBalance - amount, "Amount wasn't correctly taken from the sender");
    assert.equal(accountTwoEndingBalance, accountTwoStartingBalance + amount, "Amount wasn't correctly sent to the receiver");
  });
});


===========

web3 private key unlock & create contract


createcontract.js methond 1

var fs  = require('fs');

var Web3 = require("web3");
var provider = new Web3.providers.HttpProvider("http://192.168.99.100:18545");
var web3 = new Web3(provider);

console.log("before web set account: %o", web3.eth.defaultAccount);
const privateKey = 'd05bd152f3d71ff5f91830f3ccc1090fb670c7026ebf8c2136d4e5090d59398d';
const account = web3.eth.accounts.privateKeyToAccount('0x' + privateKey);
web3.eth.accounts.wallet.add(account);
console.log("private key import to account: %o", account)
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);
}

const certContract = new web3.eth.Contract(certjson.abi);
certContract.options.data = certjson.bytecode;
certContract.options.from = '0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176'
certContract.options.gas = '4700000'

console.log("web3 version: %o", web3.version)
web3.eth.getAccounts().then(o=>{console.log("Accounts: %o", o)})

certContract.deploy().send()
.on('error', (error) => {
    console.log("error: %o", error)
})
.on('transactionHash', (transactionHash) => {
    console.log("transactionHash: %o", transactionHash)
})
.on('receipt', (receipt) => {
    // receipt will contain deployed contract address
    console.log("receipt: %o", receipt)
    console.log("receipt.contractAddress: %o", receipt.contractAddress) 
})
.on('confirmation', (confirmationNumber, receipt) => {
    console.log("confirmationNumber: %o", confirmationNumber)
    console.log("confirmation receipt: %o", receipt)
})
.then(function(newContractInstance){
    if (typeof newContractInstance.options.address !== 'undefined') {
        console.log('Contract mined! address: ' + newContractInstance.options.address);
    }else{
        console.log("newContractInstance.address is undefined!")
    }
});

createcontract.js methond 2

var fs  = require('fs');

var Web3 = require("web3");
var provider = new Web3.providers.HttpProvider("http://192.168.99.100:18545");
var web3 = new Web3(provider);

console.log("before web set account: %o", web3.eth.defaultAccount);
const privateKey = 'd05bd152f3d71ff5f91830f3ccc1090fb670c7026ebf8c2136d4e5090d59398d';
const account = web3.eth.accounts.privateKeyToAccount('0x' + privateKey);
web3.eth.accounts.wallet.add(account);
console.log("private key import to account: %o", account)
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);
}

const certContract = new web3.eth.Contract(certjson.abi);
certContract.options.data = certjson.bytecode;
certContract.options.from = '0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176'
certContract.options.gas = '4700000'

console.log("web3 version: %o", web3.version)
web3.eth.getAccounts().then(o=>{console.log("Accounts: %o", o)})

// 怖署合約
var TxHash;

console.log("######## promise all ##############");

const getNonce = () => {
    return new Promise((resolve, reject) => {
        web3.eth.getTransactionCount(web3.eth.defaultAccount, (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 sendRawTransaction = (rawTx) => {
//     const privateKey = "d05bd152f3d71ff5f91830f3ccc1090fb670c7026ebf8c2136d4e5090d59398d";
//     const tx = new Tx(rawTx);
//     const privateKeyBuffer = Buffer.from(privateKey, 'hex');
//     tx.sign(privateKeyBuffer);
//     const serializedTx = tx.serialize();
//     web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
//         console.log('Error:', err);
//         console.log('Hash:', hash);
//     });
// }
  
Promise.all([getNonce(), getGasPrice()]).then(values => {
    // const rawTx = {
    //     to: '0x203D17B4a1725E001426b7Ab3193E6657b0dBcc6',
    //     gasLimit: web3.toHex(1000000),
    //     value: web3.toHex(web3.toWei('0.1', 'ether')),
    //     nonce: values[0],
    //     gasPrice: values[1]
    // };
    // console.log(rawTx);
    // return(rawTx);

       console.log("nonce: %s", web3.utils.hexToNumber(values[0]));
       console.log("GasPrice: %s", web3.utils.hexToNumber(values[1]));

       web3.eth.estimateGas({from: "0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176",data: contractjson.bytecode.object}).then(o=>{console.log("estimateGas: %o", o);})

    web3.eth.sendTransaction({
        from: "0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176", // web3.eth.coinbase,  // web3.eth.getAccounts() 第一筆
        data: certjson.bytecode,
        nonce: values[0],
        gasPrice: values[1],
        gas: 4700000
    }).then(o=>{
        console.log("txhash object: %o", o); 
        TxHash = o.transactionHash;
        console.log("TxHash: %o", TxHash)
    
        web3.eth.getTransactionReceipt(TxHash).then(o=>{
            console.log("check contractAddress object: %s", o.contractAddress); 
        });    
    })
    .catch(e => console.log("sendTransaction error: %o", e));
})
.then(console.log("create transaction ok!"))
.catch(e => console.log("promise all error: %o", e))


node createcontract.js


===========
every 10sec create contract

First: fixed contract



pragma solidity >=0.4.25 <0.7.0;


contract MetaCoin {
 mapping (address => uint) balances;

 event Transfer(address indexed _from, address indexed _to, uint256 _value);

 constructor() public {
  balances[msg.sender] = 10000;
 }

 function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
  if (balances[msg.sender] < amount) return false;
  balances[msg.sender] -= amount;
  balances[receiver] += amount;
  emit Transfer(msg.sender, receiver, amount);
  return true;
 }

 function getBalance(address addr) public view returns(uint) {
  return balances[addr];
 }
}

Promise.all method & web3.eth.sendTransaction


var fs  = require('fs');

var Web3 = require("web3");
var provider = new Web3.providers.HttpProvider("http://192.168.99.100:18545");
var web3 = new Web3(provider);

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 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, (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));
        })
    })
}

Promise.all([getNonce(), getGasPrice()]).then(values => {
    console.log("values: Nonce %s  GasPrice %s", web3.utils.hexToNumber(values[0]), web3.utils.hexToNumber(values[1]));
}).then(console.log("create transaction ok!"))
.catch(e => console.log("promise all error: %o", e))

setInterval( () => {

Promise.all([getNonce(), getGasPrice()]).then(values => {
    console.log("nonce: %s", web3.utils.hexToNumber(values[0]));
    console.log("GasPrice: %s", web3.utils.hexToNumber(values[1]));
   
   web3.eth.estimateGas({from: "e79d33e93bd888b35e055f1a12d876354729037b",data: contractjson.bytecode.object}).then(o=>{console.log("estimateGas: %o", o);})

    web3.eth.sendTransaction({
        from: "e79d33e93bd888b35e055f1a12d876354729037b", // web3.eth.coinbase,  // web3.eth.getAccounts() 第一筆
        data: contractjson.bytecode.object,
        nonce: values[0],
        gasPrice: 20000000000, //20,000,000,000
        gas: 181949 //181,949
    }).then(o=>{
        console.log("txhash object: %o", o); 
        TxHash = o.transactionHash;
        console.log("TxHash: %o", TxHash)
    
        web3.eth.getTransactionReceipt(TxHash).then(o=>{
            console.log("check contractAddress object: %s", o.contractAddress); 
        });    
    })
    .catch(e => console.log("sendTransaction error: %o", e.message));
})
.then(console.log("create transaction ok!"))
.catch(e => console.log("promise all error: %o", e.message))

}, Math.random() * 10000);


every 5sec create contract & web3 contract method


var fs  = require('fs');

var Web3 = require("web3");
var provider = new Web3.providers.HttpProvider("http://192.168.99.100:18545");
var web3 = new Web3(provider);

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 contractjson;
var contractjsonpath = './MetaCoin.json';

try {
    contractjson = JSON.parse(fs.readFileSync(contractjsonpath));
} catch (err) {
    console.error('readFileSync Error: %o', err);
}

setInterval( () => {

contractAddr = "0x46Fac13Ca8398545479bF2DA18133Aa87377b559";
contractfrom = "0xe79d33e93bd888b35e055f1a12d876354729037b";
coinOwnerAddr = "0xe79d33e93bd888b35e055f1a12d876354729037b"
sendCointoAddr = "0x5921a4C1B13afbD4b61d63e9c7BD47741C47B176";

var metacoinContract = new web3.eth.Contract(contractjson.abi, contractAddr);

metaCoinContract.methods.getBalance(coinOwnerAddr).call({
    from: contractfrom,
    gasPrice: 20000000000, //20,000,000,000
    gas: 181949
})
.then(o=>{console.log(coinOwnerAddr+" getBalance: %o", o)});

metaCoinContract.methods.sendCoin(sendCointoAddr, 10).send({
    from: contractfrom,
    gasPrice: 20000000000, //20,000,000,000
    gas: 181949
})
.then(o=>{console.log("sendCoin: %o", o)});

metaCoinContract.methods.getBalance(sendCointoAddr).call({
    from: contractfrom,
    gasPrice: 20000000000, //20,000,000,000
    gas: 181949
})
.then(o=>{console.log(sendCointoAddr+" getBalance: %o", o)});

}, Math.random() * 5000);

// .on('transactionHash', function(transactionHash){
//     console.log("transactionHash: %o", transactionHash)
// })
// .on('receipt', function(receipt){
//     console.log("receipt: %o", receipt)
//     console.log("receipt.contractAddress: %o", receipt.contractAddress) 
// })
// .on('confirmation', function(confirmationNumber, receipt){
//     console.log("confirmationNumber: %o", confirmationNumber)
//     console.log("confirmation receipt: %o", receipt)
// })
// .on('error', function(error){console.log("error: %o", error.message)});


=====
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/

Architecture Behind Sila Ethereum Transactions

https://silamoney.com/2019/07/08/using-aws-lambda-sqs-with-web3/
https://silamoney.com/2019/07/08/using-aws-lambda-sqs-with-web3-2/



Major components

  1. DynamoDB to store the nonce associated with ethereum addresses authorized to send ethereum smart contract transactions
  2. Lambda functions triggered by SQS events for SilaToken issuance, redemption, and transfer messages
  3. Ethereum RPC EC2 servers running Parity Ethereum client
  4. AWS Secrets Manager to store private keys being used to sign the transactions
  5. Orchestrator as a bridge between REST API, ACH, and ethereum transactions. Orchestrator is a piece of code that handles the transaction state and reroutes them to right queue.
  6. SQS as an interface between different services like REST API, ACH, Ethereum issuance, redemption, and transfers.


Transaction Lifecycle

Messages for SilaToken issuance, redemption, and transfer comes in through Sila APIs. Dependent on the action (issue, redeem, and transfer), the message is sent to the relevant queue by Orchestrator, which in turn triggers the send transaction Lambda function.
That sends the transaction, signed by Sila’s authorized address, to Ethereum node and increases the nonce in the database by one, for subsequent transactions. The message is deleted from the ethereum transaction queue and sent to the ethereum pending queue with the transaction hash and nonce, then sent with the block number appended in the message history. Replace and check for transaction send failure if there is a bad RPC connection.

play around with sila api

Constructing a Transaction:

constructing transaction

Sending a transaction:

AWS Lambda SQS Fintech

Nonce management

After experimenting with several ways to manage the authorized address nonce we settled on storing it in a database, as it is faster to retrieve and update there than making a Web3 call to the RPC server and waiting for the transaction to be mined. It has its pitfalls, however. For example, subsequent transactions can get stuck until previous transactions have been mined, but that’s why we have three Lambda functions that are watching just the pending transactions — and we’ll discuss how to handle pending ethereum smart contract transactions in the next section.
Nonce management is not as straightforward, as we have three Lambda functions that can send transactions. In our case we have conditions in place that are dependent on message history.

Deciding gas price & gas limit

Gas limit is set based on the amount of computation involved in the smart contract function call. However we can play around with the gas price to make sure transactions are being mined in the desired time. We use a modified version of eth_gas_station engine to decide the gas price, based on the network mining requirements.

Handling Transactions in Pending Queue

Let’s dive deeper into the three Lambda functions that are watching the pending queue . . .

1. Check pending transactions for success or a fail

Previously we discussed how we appended the tx_hash, nonce and sent_at_blockNumber in the message history, we use tx_hash and web3 module to get the transaction status. The transaction status can be 0,1, or null depending on if the transaction has been mined successfully. Status 0 and 1 both result in a nonce increment for the authorized address, as the transaction was mined in some block. If the status is 0, which means the transaction failed, we retry the transaction by sending it back to the transaction queue. Each transaction is restricted to a maximum of 3 retries, after which it is dumped into Orchestrator. If the status is 1 which means that the transaction was successful, a message with success update is sent to Orchestrator.

2. Replacing stuck transactions

If the transaction hash gets a null and transaction has been pending in the node memory pool for a long time, consider how we appended the sent_at_block number and nonce in the message history. We get the current block number, using Web3, and compare the difference; if the difference is more than 80 blocks (and the difference can be set to higher or lower), which means the transaction has been pending for 80 blocks, we replace the transaction with a higher gas price, keeping the nonce value the same as in the message.

3. Handling transaction send failures

If you play with Ethereum long enough you will have certain cases where you are unable to find the sent transaction in the node memory pool. This means the transaction never hit the Ethereum RPC server, but we have another Lambda function that will redirect the transaction message to the queue.

Like this article? Share it with your network!
About Sila
Sila provides Banking and Payments Infrastructure-as-a-Service for teams building the next generation of financial products and services. Our banking API replaces the need for integrating with legacy financial institutions saving you months of development time and thousands in legal and regulatory expenses.

haproxy failover backup server

https://www.haproxy.com/blog/failover-and-worst-case-management-with-haproxy/


Normal backup servers: In this case, s3 will be used first, until it fails, then s4 will be used.



frontent ft_app
 bind 10.0.0.1:80
 default_backend bk_app_main
backend bk_app_main
 server s1 10.0.0.101:80 check
 server s2 10.0.0.102:80 check
 server s3 10.0.0.103:80 check backup
 server s4 10.0.0.104:80 check backup


Multiple backup servers: In this case, both s3 and s4 will be used if they are available.

option allbackups



frontent ft_app
 bind 10.0.0.1:80
 default_backend bk_app_main
backend bk_app_main
 option allbackups
 server s1 10.0.0.101:80 check
 server s2 10.0.0.102:80 check
 server s3 10.0.0.103:80 check backup
 server s4 10.0.0.104:80 check backup

nginx failover without load balancing

https://serverfault.com/questions/480241/nginx-failover-without-load-balancing


pstream backend {
    server 1.2.3.4:80 fail_timeout=5s max_fails=3;
    server 4.5.6.7:80 backup;
}

server {
    listen 80;
    server_name whatevs.com;

    location / {
        proxy_pass http://backend;
    }
}


https://www.cnblogs.com/biglittleant/p/8979887.html

backup 预留的备份服务器,当其他所有的非backup服务器出现故障或者忙的时候,才会请求backup机器,因为这台集群的压力最小。

max_fails 允许请求失败的次数,默认是1,当超过最大次数时,返回proxy_next_upstream模块定义的错误。0表示禁止失败尝试,企业场景:2-3.京东1次,蓝汛10次,根据业务需求去配置。

fail_timeout,在经历了max_fails次失败后,暂停服务的时间。京东是3s,蓝汛是3s,根据业务需求配置。常规业务2-3秒合理。

例:如果max_fails是5,他就检测5次,如果五次都是502.那么,他就会根据fail_timeout 的值,等待10秒,再去检测。


https://blog.51cto.com/wangwei007/1103727

ethereum Nonce collisions

https://hackernoon.com/ethereum-blockchain-in-a-real-project-with-500k-users-f85ee4821b12

Nonce collisions
Nonce collisions were another mysterious thing we’ve encountered when trying to scale the number of Geth nodes in order to cover the case when one node crashes. It turns out that


We used a simple load balancer before the three Geth nodes, which was sending each transaction to one of the three nodes. The problem was that each time we submitted many transactions at once, some of those transactions were mysteriously disappearing. It took a day or two until we finally figured out that this was a problem with nonce collisions.

When you are submitting raw transactions to the network you are fine, because you keep track of nonce numbers yourself. In this case you just need a node to publish raw transactions to the network. But in the case you are using an account unlocking mechanism built into the node and do not specify the nonce when publishing transactions (with web3 or so), the node tries to pick the appropriate nonce value itself and then signs a transaction.

Because of the network delays, in the case two nodes receive the same transaction publishing request, they can generate the same nonce value. At the moment of receiving the transaction publishing request they don’t know that they both received a transaction with the same nonce. Thus, when propagating these transactions through the network, one of them will eventually be dropped because its “transaction nonce is too low”.

To fix nonce collisions introduced by adding a load balancer to a system, we needed to create a different kind of load balancer. For example, a load balancer which always uses one particular node and switches to another node only if the first one is down.

ethereum Proper Transaction Signing nonce

https://ethereum.stackexchange.com/questions/12823/proper-transaction-signing


const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
const config = require('./config');

const web3 = new Web3(new Web3.providers.HttpProvider(config.provider)); //link provided by Infura.io
web3.eth.defaultAccount = "0xc929c890f1398d5c1ecdf4f9ecec016906ac9f7f";

const getNonce = () => {
  return new Promise((resolve, reject) => {
    web3.eth.getTransactionCount(web3.eth.defaultAccount, (error, result) => {
      if(error) reject(error);
      resolve(web3.toHex(result));
    })
  })
}
const getGasPrice = () => {
  return new Promise((resolve, reject) => {
    web3.eth.getGasPrice((error, result) => {
      if(error) reject(error);
      resolve(web3.toHex(result.toNumber()));
    })
  })
}

const sendRawTransaction = (rawTx) => {
  const privateKey = "190b820c2627f26fd1b973b72dcba78ff677ca4395c64a4a2d0f4ef8de36883c";
  const tx = new Tx(rawTx);
  const privateKeyBuffer = Buffer.from(privateKey, 'hex');
  tx.sign(privateKeyBuffer);
  const serializedTx = tx.serialize();
  web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
      console.log('Error:', err);
      console.log('Hash:', hash);
  });
}

Promise.all([getNonce(), getGasPrice()])
  .then(values => {
    const rawTx = {
      to: '0x203D17B4a1725E001426b7Ab3193E6657b0dBcc6',
      gasLimit: web3.toHex(1000000),
      value: web3.toHex(web3.toWei('0.1', 'ether')),
      nonce: values[0],
      gasPrice: values[1]
    };
    console.log(rawTx);
    return(rawTx);
  })
  .then(sendRawTransaction)
  .catch(e => console.log(e))

ring buffer

https://zhen.org/blog/ring-buffer-variable-length-low-latency-disruptor-style/

https://github.com/smartystreets-prototypes/go-disruptor

ethereum transaction template

https://ethereum.stackexchange.com/questions/50042/why-does-sendsignedtransaction-return-a-tx-hash-but-does-not-post-to-the-rinkeby


window.web3 = new Web3(new Web3.providers.HttpProvider(endpoint));

sendEther() {
    const fromAccount = **acct1**;
    const toAccount   = **acct2**;

    const rawTransaction    = this.makeRawTransaction(fromAccount, toAccount);
    const signedTransaction = this.makeSignedTransaction(rawTransaction);
    const serializedTransaction = `0x${signedTransaction.serialize().toString('hex')}`;

    window.web3.eth.sendSignedTransaction(serializedTransaction, (error, result) => {
        if(!error) {
          console.log(`Transaction hash is: ${result}`);
          this.setState({
            etherscanUrl: `https://rinkeby.etherscan.io/tx/${result}`,
            error: null
          });

        } else {
          this.setState({ error: error.message })
          console.error(error);
        }
    });
  }

  makeSignedTransaction(rawTransaction) {
    const privateKey   = '**************';
    const privateKeyX  = new Buffer(privateKey, 'hex');
    const transaction  = new EthTx(rawTransaction);
    transaction.sign(privateKeyX);

    return transaction;
  }

  makeRawTransaction(fromAccount, toAccount) {
    const { exchangeRate } = this.props;
    const amount = (1 / exchangeRate) * 5;

    return ({
      nonce: window.web3.utils.toHex(window.web3.eth.getTransactionCount(fromAccount)),
      to: toAccount,
      gasPrice: window.web3.utils.toHex(100000000000),
      gasLimit: window.web3.utils.toHex(100000),
      value: window.web3.utils.toHex(window.web3.utils.toWei(`${amount}`, 'ether')),
      data: ''
    });
  }

[轉]Windows、WSL 与 Linux 的性能对比

https://www.cnbeta.com/articles/tech/922349.htm

尽管执行了各种各样的测试,但是如果对在七个不同操作系统上成功运行的所有测试取几何平均值,可以得出这样的结论:

Windows 10 Build 19008 的总体性能要比 Build 18362 版本好,而 WSL 的性能并没有太大变化

WSL2 比 WSL 的性能确实稍好一些,这是因为在 I/O 或网络活动繁重的工作负载的情况下前者性能要好得多

在这种特殊的 Core i9 7960X 场景下,运行 Ubuntu Linux 的速度总体上比最快的 Windows 配置快 27%

有兴趣的朋友可查看这份更详细的 OpenBenchmarking.org 结果文件,以深入研究这些 Windows / WSL / Linux 基准测试内容。

geth attach



geth --exec "eth.blockNumber" attach --datadir ./
geth --exec "eth.syncing" attach --datadir ./
geth --exec "admin.peers" attach --datadir ./
geth --exec "clique.getSnapshot()" attach --datadir ./

watch -n 2 'geth --exec "clique.getSnapshot()" attach --datadir ./'

geth-prometheus

https://github.com/karalabe/geth-prometheus


https://blog.ethereum.org/2019/07/10/geth-v1-9-0/

You can quickly reproduce the above charts via my clone of Maxim Krasilnikov’s project by running docker-compose up in the repo root and accessing http://localhost:3000 with the admin/admin credentials. Alternatively, you can view my testing snapshot on Raintank, or import this dashboard into your own Grafana instance

源碼掃瞄

Checkmarx
Fortify

ethereum geth check transaction

geth console


## get balance

eth.getTransaction("")
eth.getTransactionReceipt("")

EX: transaction id 0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83
eth.getTransaction("0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83")
eth.getTransactionReceipt("0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83")


## get transaction count

eth.getTransactionCount()
eth.getTransactionCount(, "pending")

EX: transaction id 0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83
eth.getTransactionCount("0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83")
eth.getTransactionCount("0x8dfaa1b5d2e660ee2d3aa9fd0eeb33cc726d50122790e882a914ffd7d02e3a83", "pending")


## check pending queued

txpool.status

EX:
{
pending: 0,
queued: 5
}

融資

目前好像國泰比較優
年利率2% 手續費2千
一年到期續約不用手續費
這些都是基本條件不需要談

對啊,不過國泰大概是給年薪的3倍額度

年薪50萬,就150萬

聯邦18個月後,要還一次本金嗎?
聯邦不用還本金
國泰也不用


所以500萬,屆滿300萬,18個月後,直接續新約齁?

銀行、證券金融,國泰、聯邦、元大證金,就沒這種規定

查驗 驗收

.需求書內 合約 改成 契約

勞務請購 準備文件
1. 購案核定清單
2. 自我檢核表
3. 報價單
4. 需求書
5. 承攬商 (有派人力到 中心/公司 工作情況)
最後 預估金額分析表 (簽核過財會後,請購人員會給予後填寫)

案子的負責「採購人員」是: AAA
先請試填請購單後,截取畫面併相關文件給採購人員確認是否正確後,再正式填寫請購單
會科問題 BBB 會計人員

金額比例 300 200 (依期數 如這裡500 分二期)
需求書上 兩次:10/30、6/31
付款注意:年底可能會關帳,要提前,建議一個月為主

特別注意:查驗和驗收不同,案子通常第一期為查驗,第二期為驗收,兩者皆為組長(負責主管),如沒空,可找代理人,查驗/驗收需求項目、文件順序需按照需求書

第一期查驗:
.我方需要確認資料、系統和文件是否正確,系統檔案可存放光碟(建議全放)
.查驗文件依需求書需求項目為主,再說明查驗或驗收順序已備齊
.廠商準備現場DEMO及列印文件,務必提前一到二星期準備
.另廠商需寄送EMail告知開發完畢,可進行查驗或驗收,印該EMail代表收到開發完畢文件
.查驗文件上的完成覆約日期為收到EMail為主,查驗測試時間則為實際排定查驗測試日期

第二期驗收:
.需先再跑查驗流程(非第一期查驗),再驗收
.需自行把系統自行跑過一次,代表有實際確認過
.其他同第一期
.查驗過後,將相關資料給予採購人員,會協助安排組長驗收時間,自行安排會議室
.驗收記錄給予廠商,進行發票開立作業
.收到廠商發票後交給採購人員

[轉]Flutter 状态管理指南之 Provider

https://zhuanlan.zhihu.com/p/70280813

[轉]Flutter 全局状态管理之 Provider 初探

https://juejin.im/post/5d8f324ee51d45781e0f5dca

一、什么是全局状态管理

当我们在使用 Flutter 进行应用开发时,可能需要不同的页面共享应用或者说变量的状态,当这个状态发生改变时,所有依赖这个状态的 ui 都会随之发生改变。在同一个页面中还好说,直接通过 setState 就可以达到目的,要是不同的页面呢,或者当应用变得非常复杂,页面非常多的时候,这个时候全局状态管理就显得非常重要了。
在 Flutter 中,状态管理可以有如下几种方式:
1、setState
flutter 中最简单使 ui 根据状态发生改变的方式。
2、 InheritedWidget & InheritedModel
InheritedWidget 和 InheritedModel 是 flutter 原生提供的状态管理解决方案。 当InheritedWidget发生变化时,它的子树中所有依赖了它的数据的Widget都会进行rebuild,这使得开发者省去了维护数据同步逻辑的麻烦。
3、Provider & Scoped Model
Provider 与 Scoped Model 都属于第三方库,两者使用起来差不多,其中 Provider 是 Google I/O 2019 大会上官方推荐的状态管理方式。
4、Redux
在 Redux 状态管理中,所有的状态都储存在Store里,Flutter 中的 Widget 会根据这个 Store 去渲染视图,而状态的改变也是通过 Reduex 里面的 action 来进行的。
5、BLoC / Rx
BLoC的全称是 业务逻辑组件(Business Logic Component)。就是用reactive programming方式构建应用,一个由流构成的完全异步的世界。 BLoc 可以看作是 Flutter 中的异步事件总线,当然在除了 BLoc 外,Flutter 中有专门的响应式编程库,就是RxDart,RxDart是基于ReactiveX标准API的Dart版本实现,由Dart标准库中Stream扩展而成。

作者:Flutter编程开发
链接:https://juejin.im/post/5d8f324ee51d45781e0f5dca
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。