EExcel 丞燕快速查詢2

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

firebase functions cold start use Express.js node.js get problem

System on firebase functions always have problems that code start.

https://medium.com/@siriwatknp/cold-start-workaround-in-firebase-cloud-functions-8e9db1426bd3

So


google office

https://firebase.google.com/docs/functions/networking


const http = require('http');
const functions = require('firebase-functions');

// Setting the `keepAlive` option to `true` keeps
// connections open between function invocations
const agent = new http.Agent({keepAlive: true});

exports.function = functions.https.onRequest((request, response) => {
    req = http.request({
        host: '',
        port: 80,
        path: '',
        method: 'GET',
        agent: agent, // Holds the connection open after the first invocation
    }, res => {
        let rawData = '';
        res.setEncoding('utf8');
        res.on('data', chunk => { rawData += chunk; });
...


Two line let me confused. Not only me.


const agent = new http.Agent({keepAlive: true}); 
agent: agent, // Holds the connection open after the first invocation

Some guy same me.


Get same problem.

https://stackoverflow.com/questions/56912118/how-can-i-maintain-persist-a-cloud-functions-connection-using-expressjs


Success??

https://stackoverflow.com/questions/55425015/how-to-keep-alive-dialogflow-firebase-function-to-avoid-new-connection-time-wast

Thanks Max. However I found the answer to this problem from the same link I posted above (i.e. firebase.google.com/docs/functions/networking). Just adding two lines of code solved the problem. Now response is quite prompt. I added following lines: 1. const agent = new http.Agent({keepAlive: true}); 2. agent: agent, – Vipul Sisodia Apr 2 '19 at 19:04


See Express.js

https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_new_agent_options


Not thing can Try.


Other way

https://medium.com/@onufrienkos/keep-alive-connection-on-inter-service-http-requests-3f2de73ffa1

https://stackoverflow.com/questions/60667847/unable-to-verify-leaf-signature-from-request-with-firebase-functions-node-js-wit

index.js

require('https').globalAgent.keepAlive = true;

const functions = require('firebase-functions');
const express = require('express');
const app = express();

...

exports.api = functions.runWith(runtimeOpts).https.onRequest(app);

require('https').globalAgent.keepAlive = true;

Try by yourself.


新增說明文字


mysql json mariadb

最近寫mysql 發現 原來 mysql 在json內容時,也有支援一些操作

 https://www.cnblogs.com/chuanzhang053/p/9139624.html

 https://medium.com/micheh/%E5%9C%A8-mysql-%E4%BD%BF%E7%94%A8-json-5796a65701ad 

再加上 mysql 還有另一個譆能 虛疑欄位 GENERATED ALWAYS AS

 http://blog.changyy.org/2017/09/mysql-json-mysql-57.html

 基本上可以把json內的某欄位值當成 virutal colume, 直接輸出 覺得這樣可以玩出很多變化 

https://www.cnblogs.com/waterystone/p/5626098.html

nodejs node.js console.log util.format ...args for logging log

For logging mulit args with "%O"

const util = require('util');
function d(...args) {
  if (typeof (console) !== 'undefined') {
    console.log('[Logging]', util.format(...args));
  }
}

[轉]網站使用體驗三大核心指標 – LCP, FID, CLS

https://www.darrenhuang.com/core-web-vitals-lcp-fid-cls.html?fbclid=IwAR2-n-h0j-BR73sD4Vsino1ObtjDyVe3xkhNcs7xmtcn14Kk84rWO-06lPs 瀏覽器插件 這是官方出的Chrome挿件,能夠在瀏覽時即時回報該網頁的LCP, FID, CLS。

nodejs express cache redis

https://sematext.com/blog/expressjs-best-practices/

const express = require('express')
const app = express()
const redis = require('redis')
​
const redisClient = redis.createClient(6379)
​
async function getSomethingFromDatabase (req, res, next) {
  try {
    const { id } = req.params;
    const data = await database.query()
​
    // Set data to Redis
    redisClient.setex(id, 3600, JSON.stringify(data))

    res.status(200).send(data)
  } catch (err) {
    console.error(err)
    res.status(500)
  }
}
​
function cache (req, res, next) {
  const { id } = req.params
​
  redisClient.get(id, (err, data) => {
    if (err) {
      return res.status(500).send(err)
    }

    // If data exists return the cached value
    if (data != null) {
      return res.status(200).send(data)
    }
​
   // If data does not exist, proceed to the getSomethingFromDatabase function
   next()
  })
}
​
​
app.get('/data/:id', cache, getSomethingFromDatabase)
app.listen(3000, () => console.log(`Server running on Port ${port}`))

vs code 無法使用eslint

In personal setting.json for vs code

"eslint.workingDirectories": [
    { "mode": "auto" }
],

Promise.all map



const arr = {};

await Promise.all(
  UsersQuery.map(async function (data) {
    const city = await db.sequelize.query(`
      select * from city
    `, 
      type: db.sequelize.QueryTypes.SELECT 
    });

    arr[data.user_id] = city[0].name;

  })
}


UsersQuery.forEach(async function (data, index) {
  this[index].name = arr[data.user_id];
}, UsersQuery);

sqlmap



docker https://hub.docker.com/r/googlesky/sqlmap

執行指令:

docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap -h

GET

docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='https://test.com/date=2020-04-01' --level=5 --risk=3

POST & header token

docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='http://oo.xx.oo.xx:5000/user/info' --headers='Authorization: bearer eyJhbGcoooooxxxxxoooooxx......' --data='{id: "u123"}' --level=5 --risk=3

nodejs moment moment-timezone

Use express, moment, moment-timezone


const moment = require('moment-timezone');


app.get('/moment', (req, res) => {
  const datestr = '2020-07-01';

  res.status(200).json({
    local_offset: moment(datestr).utc(),
    local_unix: moment(datestr).unix(),
    zone0_unix: moment(datestr).zone(0).unix(),
    zone8_unix: moment(datestr).zone(8).unix(),
    timezone0_unix: moment.tz(datestr, 'GMT').unix(),
    timezone8_unix: moment.tz(datestr, 'Asia/Taipei').unix(),
  });
});

// No use, just for keep 
function dateForTimezone(offset, d) {
  // Copy date if supplied or use current
  d = d? new Date(+d) : new Date();

  // Use supplied offset or system
  offset = offset || -d.getTimezoneOffset();
  // Prepare offset values
  var offSign = offset < 0? '-' : '+'; 
  offset = Math.abs(offset);
  var offHours = ('0' + (offset/60 | 0)).slice(-2);
  var offMins  = ('0' + (offset % 60)).slice(-2);

  // Apply offset to d
  d.setUTCMinutes(d.getUTCMinutes() - offset);

  return offSign + offHours + ':' + offMins;

  // Return formatted string
  return d.getUTCFullYear() + 
    '-' + ('0' + (d.getUTCMonth()+1)).slice(-2) + 
    '-' + ('0' + d.getUTCDate()).slice(-2) + 
    'T' + ('0' + d.getUTCHours()).slice(-2) + 
    ':' + ('0' + d.getUTCMinutes()).slice(-2) + 
    ':' + ('0' + d.getUTCSeconds()).slice(-2) + 
    '.' + ('000' + d.getUTCMilliseconds()).slice(-3) +
    offSign + offHours + ':' + offMins; 
  
}

IMPORT


Server timezone 0

Client time zone +8


Server run result:


{
  "local_offset": "2020-06-30T16:00:00.000Z",
  "local_unix": 1593532800,
  "zone0_unix": 1593532800,
  "zone8_unix": 1593532800,
  "timezone0_unix": 1593561600,
  "timezone8_unix": 1593532800
}



Client run result:


{
  "local_offset": "2020-07-01T00:00:00.000Z",
  "local_unix": 1593561600,
  "zone0_unix": 1593561600,
  "zone8_unix": 1593561600,
  "timezone0_unix": 1593561600,
  "timezone8_unix": 1593532800
}


Conclusion



moment().zone().unix()  Auto fix zone / utc

moment("").tz("GMT").unix()  Auto fix zone / utc



moment().tz("", "GMT").unix()  No auto fix zone / utc

typeorm connection



const typeorm = require("typeorm");
const connectionManager = require("typeorm").getConnectionManager();

  //const connectionManager = typeorm.getConnectionManager();
  const connected = connectionManager.has("default");
  if(!connected){
      // ? load connection options from ormconfig or environment
        //const connectionOptions = await getConnectionOptions();
        connectionManager.create({
          //name: "default",
          type: "mysql",
          // "extra": {
          //   "socketPath": "/cloudsql/ooxxooxx"
          // },
          host: "oo.xx.oo.xx",
          port: 3306,
          username: "root",
          password: "ooxxooxx",
          database: "ooxxdb",
          synchronize: false,
          logging: true, // this.env === 'dev' ? true : false
          ssl: SSL,
          keepConnectionAlive: false,
      });
  }

  try {
    db = connectionManager.get();
    if(!connected){ 
        await db.connect(); 
        console.log('connect .... OK!');
    }
  }catch(error) {
    console.log("TypeORM Error: ", error);
  };

  var ranks = await db.query("select * from users");

Sequelize 基本認識

# Sequelize 基本認識

## 1. Timestamps
https://sequelize.org/v5/manual/models-definition.html#timestamps

## 2. Database synchronization
https://sequelize.org/v5/manual/models-definition.html#database-synchronization

建議不要直接使用於正式環境,應該在測試建立後,取得對應 sql 碼後,在正式上線時,手動更新正式 DB 資料結構

**2.1** 使用 sync 建立的 table name 會加上 s
**2.2** 正常情況下,對 table 操作盡可能還是已手動為主,雖然 Sequelize 有提供一些操作,但減少使用比較安全,當手動操作完畢後,應該把 raw sql 匯出備份,正式上線時,再手動更新

## 3. Modeling a table 建立
https://sequelize.org/v5/manual/getting-started.html

```
const Model = Sequelize.Model;
class User extends Model {}
User.init({
```

建議使用

```
sequelize.define:'user', {
// attributes
firstName: {

```

原因,看起來簡單多了

3.1 Model 操作
https://sequelize.org/v5/manual/models-usage.html

## 4. Raw queries
https://sequelize.org/v5/manual/raw-queries.html

基本當join比較複雜建議使用,因為清楚、效率可控,或更複雜的 sub sql 都可以進行,避免 ORM 處理不當,造成效能大幅下降

**4.1** 回傳是 [results, metadata]
**4.2** 有使用參數情況下,務必使用 Replacements 千萬不要直接raw sql + 參數

西方式傲慢

西方式傲慢 https://youtu.be/-3lqr6Ys_zQ?t=697

中國為西方贏得時間,西方卻浪費了它 張彥
https://cn.nytimes.com/opinion/20200314/china-response-china/zh-hant/

普立茲獎 張彥
https://zh.wikipedia.org/zh-tw/%E5%BC%A0%E5%BD%A6_(%E7%BE%8E%E5%9B%BD%E8%AE%B0%E8%80%85)



連 柳葉刀的主編 中國傳遞了非常清淅的訊息,可是我們浪費了整整2個月
https://news.sina.com.tw/article/20200401/34733366.html
https://www.facebook.com/watch/?v=538201007134058

[轉]Go 交叉編譯

https://ithelp.ithome.com.tw/articles/10225188

在Windows上編譯

To MacOs

SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go

To Linux

SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go

To Windows ???

go build main.go


在Linux上編譯

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go


CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go


CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

javascript firestore object sort



  const bookListsQuery = await modules.firestore.collection('books')
    .get();

  const sortedObj = Object.values(bookListsQuery.docs).sort(function(a, b){
    console.log('a %s  b %s', a.data().order, b.data().order)
    return Number(a.data().order) > Number(b.data().order);
  });
        
  sortedObj.forEach(function(doc){
    console.log(doc.data())
  });


other way

object use map to array, then it sorted.


  const bookListsQuery = await modules.firestore.collection('books')
    .get();

  const sortedArr = bookListsQuery.docs.map(function (doc) {  // 轉換成array
    return doc.data()
  });

  sortedArr.sort(function compare(a, b) {
     return a.order > b.order; // 升 小->大
  });

  sortedArr.forEach(function(data){
    console.log(data.data())
  })



==========

Sorting multiple object properties with JavaScript

https://bithacker.dev/javascript-object-multi-property-sort


let students = [{
  firstName: 'John',
  lastName: 'Appletree',
  grade: 12
},{
  firstName: 'Mighty',
  lastName: 'Peachtree',
  grade: 10
},{
  firstName: 'Kim',
  lastName: 'Appletree',
  grade: 11
},{
  firstName: 'Shooter',
  lastName: 'Appletree',
  grade: 12
}];


let sortBy = [{
  prop:'grade',
  direction: -1
},{
  prop:'lastName',
  direction: 1
}];


array.sort(function(a,b){
  let i = 0, result = 0;
  while(i < sortBy.length && result === 0) {
    result = sortBy[i].direction*(a[ sortBy[i].prop ].toString() < b[ sortBy[i].prop ].toString() ? -1 : (a[ sortBy[i].prop ].toString() > b[ sortBy[i].prop ].toString() ? 1 : 0));
    i++;
  }
  return result;
})

fb 中研院研究出快篩試劑

漂亮的諧音 https://www.youtube.com/channel/UCRSmPITY7izy2F1INKMEf2g
13 小時前

中研院研究出快篩試劑,
綠媒大肆吹捧,
817們高潮連連,
綠媒說根本是大陸搶了台灣的研究功勞,
結果人家那是2月的事,
如何搶台灣3月研發出來的成果功勞?
(原來中國有坐時光機穿越未來,
抄襲台灣研究成果的能力啊)

。。。

接著衛福部被抓包,
2月就核准進口大陸快篩試劑,
但衛福部辯解說進口的是抗體試劑,
中研院研發的是抗原試劑,
(既然兩者快篩試劑不同,
那白痴綠媒說大陸搶了台灣研究功勞,
這是什麼毛病?
反正只要政治正確,
造謠就沒問題是嘛!?)

。。。

那中研院的快篩試劑何時可量產?
中研院長回覆說:
『此一問題「難以回答」。
做試劑不能為了趕進度忽略靈敏性與準確度。
而快篩何時人體試驗、量產,
都必須與衛福部、廠商密切合作,
時間難以預估。
「即使今年用不上,
也必須為未來的疫情做準備。」』

。。。

所以817在高潮一個,
根本還無法真正問世的東西。
台灣現在就是腦殘當道啊!

[轉]Keep your promises when using Cloud Functions for Firebase!

https://firebase.googleblog.com/2017/06/keep-your-promises-when-using-cloud.html?fbclid=IwAR2FuvlU2CbwjV-I75q7-WIkJyLHRYT-R3cyleEUWF3Fsq42THMCwZN6by8


const ref_p1_state = root.child(`player_states/${game_state.p1uid}`)
const ref_p2_state = root.child(`player_states/${game_state.p2uid}`)
const pr_update_p1 = ref_p1_state.update(update_p1)
const pr_update_p2 = ref_p2_state.update(update_p2)

return Promise.all([pr_update_p1, pr_update_p2])


==========

https://stackoverflow.com/questions/55430079/promise-all-does-not-wait-for-firestore-query-to-loop

nodexjs expressjs ajv apidoc converter generator restclient curl postman

ajv schema to apidoc schema
https://github.com/willfarrell/apidoc-plugin-schema

required can't product doc.


converter
https://github.com/apidoc/apidoc#converter

to swagger
https://github.com/fsbahman/apidoc-swagger

postman collection to apidoc
https://github.com/bonzzy/docmaster

RestClient -> curl -> postman

promise.all error catch

https://stackoverflow.com/questions/30362733/handling-errors-in-promise-all



Promise.all(state.routes.map(function(route) {
  return route.handler.promiseHandler().catch(function(err) {
    return err;
  });
}))
.then(function(arrayOfValuesOrErrors) {
  // handling of my array containing values and/or errors. 
})
.catch(function(err) {
  console.log(err.message); // some coding error in handling happened
});


Alternately, if you have a case where you don't particularly care about the values of the resolved promises when there is one failure but you still want them to have run, you could do something like this which will resolve with the promises as normal when they all succeed and reject with the failed promises when any of them fail:



function promiseNoReallyAll (promises) {
  return new Promise(
    async (resolve, reject) => {
      const failedPromises = []

      const successfulPromises = await Promise.all(
        promises.map(
          promise => promise.catch(error => {
            failedPromises.push(error)
          })
        )
      )

      if (failedPromises.length) {
        reject(failedPromises)
      } else {
        resolve(successfulPromises)
      }
    }
  )
}

firestore import

使用 https://github.com/dalenguyen/firestore-backup-restore
base on https://github.com/dalenguyen/firestore-import-export

能處理timestamp

filestore2json json2filestore

https://gist.github.com/sturmenta/cbbe898227cb1eaca7f85d0191eaec7e#gistcomment-2837988

ok can use. good job.

timestamp have error.

pve Transparent Failover



Ray Tracy HA 只是高可用度,他沒有不停頓 (Non-stop) 等級的容錯(FT)能力,所以只能把死掉的 VM 重開機來復原,他做不到:接手死掉 VM 當時狀態,不停頓的執行下去....

市面上可穩定商轉的 FT 軟體最便宜也要上百萬起跳....且對硬體條件有諸多限制...

還有,測試 HA 盡量採用拔電源線的方式,而不是只拔網路線,否則在複雜網路環境中,復原後可能整個 Cluster 會發生 #叢集腦裂(雖然機率很小,你還是可以賭看看)....

而且原本初階 HA 就是設計成:用來對抗 Host 全機故障,而不是對抗只有網路故障;所以即便將網路隔離,若 Host 沒掛掉的話,復原的時候都會有風險.....

完整的 HA 流程,在啟動備用 VM 之前,Cluster 會先自動下 ipmi 或 BMC 指令給隔離的 Host 強制它完全關機之後,才啟動備用 VM, 就是為了避免發生上述風險....(這個動作稱為 fence)

這裡大部分玩 cluster 的人都不知道要去設定 ipmi/bmc 做 fence; 如果有設定 fence 的話, 就可以用拔網路線來做測試了, 因為拔掉之後, fence 會自動去把那台隔離的 host 關機, 就不會發生復原之後的腦裂問題.....(當然, 你不能去拔 fence 用的那條 ipmi 網路線...🤣🤣🤣)



Jason Cheng 如果經費不多想做 FT,可以參考台灣團隊開發的 Cuju 專案,基於 kvm 實作,去年底 Proxmox 社團使用者年會該團隊講者有來分享

https://github.com/Cuju-ft/Cuju

國小台語課不教台語,教什麼

https://youtu.be/2YlD3fsszT0?t=2436


孙杨

https://www.youtube.com/watch?v=ILICiagUIQ0

http://lanxiongsports.com/posts/view/id/17753.html

228 武之璋 有書

https://www.youtube.com/watch?v=gzpCMIv3zVc

我们和世界各地的朋友,聊了聊他们那里的疫情|故事FM

https://mp.weixin.qq.com/s/PxFYCZVELj8q0ybkhxoGhQ

造一个病毒有多难|大象公会

https://mp.weixin.qq.com/s/YX98XfO6Rb4EaBT8vRp8YA

拿H1N1來對比武漢肺炎

拿H1N1來對比武漢肺炎

中間一些部份內容,讓人理解到為什麼日韓和美國都不是很在意

https://www.youtube.com/watch?v=rJiKxV4rTCQ


https://www.youtube.com/watch?v=K2TYIV6osR8



https://www.youtube.com/watch?v=K2TYIV6osR8


https://youtu.be/UBYPkjs9ve4?t=315
https://youtu.be/UBYPkjs9ve4?t=511

https://youtu.be/0RI5JsfuZKE?t=22

https://www.youtube.com/watch?v=bPvuqvc5C1M 纽约首例新冠患者未在医院治疗,纽约州长:80%都能自愈 没必要去医院
https://www.youtube.com/watch?v=AiCghCxro8o
https://www.guancha.cn/internation/2020_03_03_539596.shtml

螢幕色彩偏離值

PS42對於你的專業需求會有很大的幫助
螢幕色彩偏離值只有0.98(校色後),未校色為1.17,1F最高為6.37(其餘都在1附近)
高達75%ARGB,116%SRGB。
表現已經達到頂級水平。


目前要顯示優秀的筆電(偏離值在1以下)非常的少,普遍都在2附近

MACBOOK PRO 13的螢幕表現
https://kknews.cc/zh-tw/digital/x2k6al8.html

菲律賓 正式中止 軍事訪問協定

https://youtu.be/DiFpRW_kw8g?t=2067

吹哨 的鬼邏輯 時間線

Coronavirus TIMELINE
https://www.youtube.com/watch?v=kO5EXjFKE7U


https://youtu.be/H0trgOgKFoE?t=716


https://youtu.be/DiFpRW_kw8g?t=1608


=============
我的美國公務員生活點滴 (番外篇2)
https://www.mobile01.com/topicdetail.php?f=651&t=5981610

沒有效果的運動方式 浪費時間的肌力訓練動作

6個浪費時間的肌力訓練動作

https://www.don1don.com/archives/23096/6%E5%80%8B%E6%B5%AA%E8%B2%BB%E6%99%82%E9%96%93%E7%9A%84%E8%82%8C%E5%8A%9B%E8%A8%93%E7%B7%B4%E5%8B%95%E4%BD%9C


1. 小腿上提 (Calf Raises)
替代方案:運動員應該讓他們的小腿肌自然發展,進行深蹲、跳蠅、還有日常的運動訓練就已經足夠了。

2.下斜式臥推 (Decline Bench Press)
替代方案:建議進行站姿滑輪胸推 (Standing Cable Presses),這個動作更接近於平日的運動形態

3.大腿推蹬機 (Leg Press)
替代方案:建議進行後腳抬高蹲 (Single-Leg Rear-Foot-Elevated Split Squats),因為大多數運動動作都是依靠單腳去進行,這個訓練動作正好乎合運動員的需求。

4.槓鈴彎舉 (Bicep Curls)
替代方案:對於想要讓手臂變強壯的運動員,引體向上 ( Pull-Ups)將會是一個比較好的選擇,另外也可以配合啞鈴或槓片來增加強度。

5.腿部伸展訓練機 (Machine Leg Extensions)
替代方案:建議採用前蹲舉(Front Squats)或跨步(Lunges),兩者都需要運動員去維持身體平衡,這在運動當中是一個非常重要的能力。

6.史密斯機器 (Smith Machine)
替代方案:採用自由重量 (Free Weight)進行深蹲、抓舉等動作將會為你身體的平衡帶來挑戰,如果做相同的重量覺得太重,那就換輕一點的吧!


反駁

https://james927.pixnet.net/blog/post/57606840


9種沒有效果的運動方式

http://www.unclesam.cc/blog/9-least-effective-exercises-from-webmd/

1. 頭後方的滑輪下拉(Lat Pull-down)
只有少數人有靈活的肩關節,讓他們在進行滑輪下拉時,能保持脊椎的直挺。所以在進行這個動作,若動作不正確時,將可能導致肩膀、旋轉肌群的受傷,若滑輪的槓子撞擊到頸部的後側,可能導致頸椎(cervical vertebrae)的受傷。

2. 槓鈴肩推舉(Military Press)
比較安全的方式是置於身體前側

3. 直立上提(Upright Row)
將槓鈴往上提至下巴處,真得不可行的方式(big no-no),這會壓迫到肩膀處的神經,衝擊到肩膀。

4. 大腿推蹬機,不適的膝蓋位置(Leg Press with Poor Knee Position)
在進行推蹬的動作,不要讓膝蓋過於前彎,超過90度,這你傷害到你的背部及膝蓋。

5. 利用史密斯機器輔助進行深蹲(Squats on the Smith Machine)
在使用史密斯機器來輔助時,人們往往會將腳步跨的更加前面。(換個方式說,藉由器材來進行訓練時,有的人會依著機器,但實際上姿勢跑掉或是受傷的機會就大大的提升)。

6. 在燃燒卡路里機器上的不良動作(Bad Form on Cardio Machines)
在使用燃燒卡路里的機器(跑步機),不要將坡度或阻力設定的太強,導致你要緊握著把手。設定在一個自然的狀況下,手握輕握著把手,讓你的身體能很自然、平衡下進行運動。

7. 局部的運動(Exercises for Spot Reduction)
人們透過局部的訓練來削減特定部位的脂肪,像是大腿、髖關節、胃及手臂,這是錯誤的想法,你不能把脂肪看成是一區一區的。有興趣的話,可以查查部落格上「迷思」的文章,對於脂肪有很多的說明囉。

避免使用健身房10種常見的訓練設備(二)

https://www.unclesam.cc/blog/10-exercise-machines-to-avoid-2/

6. 坐姿旋轉機(Seated Rotation Machine)
■ 實際的效用:「因為骨盆沒有跟著胸部移動,這個動作會施加過多的扭力在脊椎上。 」
■ 較好的動作:「砍木頭(Cable Wood Chop)」,讓你的腳踝跟著軀著活動,每邊進行10~12次。

7. 坐姿大腿推蹬機(Seated Leg Press Machine)
■ 實際的效用:「在沒有緊縮髖關節、臀肌、肩膀及下背部的必要的穩定肌肉之下, 這動作通常會強迫脊迫脊椎彎曲。」
■ 較好的動作:「徒手深蹲(Body-weight Squats Bischoff, Beth)」,在下背沒有拱起的狀況下,專注在下蹲的控制,1組進行12~15次,可以增加組數來訓練肌力

8. 史密斯機器(Smith Machine)
■ 實際的效用:「 槓子是固定在機器上,呈直接升降的移動方式,並非自然而有弧度的移動。這讓膝蓋、肩膀及下背帶來壓力。」
■ 較好的動作:「徒手深蹲(Body-weight squats)」,在下背沒有拱起的狀況下,專注在下蹲的控制,1組進行12~15次,可以增加組數來訓練肌力。

9. 羅馬背伸椅(Roman Chair Back Extension Machine)
■ 實際的效用:「 重複的彎曲你的背,而壓力加壓在脊椎上,增加椎間盤受損的風險。」
■ 較好的動作:「Bird-Dog」,四足跪姿,往前伸展右手臂及往後延伸左腳,重複進行7~10次,換邊進行。

10. 羅馬起坐椅(Roman Chair Sit-up)
■ 實際的效用:「捲腹的動作會將不必要的壓力落在下背部。」
■ 較好的動作:「棒式(Plank)」,維持20~60秒。

AI bot 聊天

https://mp.weixin.qq.com/s/CAs9AOPCDa3_yM1S-OfQxQ?fbclid=IwAR2UaV2ywyPoPY5_f3QMvj10rVaNryw_XhKhRlZFB-JlNT8QHdkOIzN4gOI

[轉]虛擬機跑起來!RouterOS CHR 軟路由效能輕鬆突破 1000M!

https://www.jkg.tw/?p=2531&fbclid=IwAR0TdjR76xT3k3w_bTNPfLZ8eW9Wuri9WBGJU7xoHsQo4PDUq2M5iIN4zfc

https://youtu.be/4PzJulQTSrY?t=1016

占美 i5 4278u

口罩

一開始四大超商就是政府決定的,怎麼決定出來不知道 (透明公開又沒了),到底誰規定一定要四大超商?!

政府絕對可以跟四大超商提出要求,口罩請用成本價售出,為了人民,至於四大超商評估是否要接這個案子

同時間其他的單位 一般藥局、連鎖藥局、全聯、屈沉世、大賣場、連鎖嬰幼、連鎖寵物等等通路,
政府絕對可以提出要求,口罩請用成本價售出,為了人民,他們可以評估是否要接這個案子

有人願意賠錢 做名聲、做善事就讓他做,互蒙其利,那來合理利潤,用合理利潤來談的話,每間通路成本不同,那我都用飛機來運口罩,一個賣200,運輸成本佔120,派人去各國搶購成本佔60,合理賺20,合理吧?! 為了合理,一堆漏洞就在裡面了!

特殊時期,你要賣,就給我照成本賣

說不定就一堆企業用成本賣,大打廣告,賺名聲


轉藥局為的是什麼? 用健保卡可以管理購買人! 而不是上面說的問題,用四大超商結果是一堆人買不到,現在的推論是有人一直買一直屯,真假比例誰知,真用 真屯?!

一開始說口罩不缺,實際缺的要死,完全能理解 政府本來在特定時期就需要說一些幹話,跟大陸一樣,在特殊時期也是要說說幹話:「中央已經掌握住情況,民眾無需恐荒」


要控制價格,讓民眾檢舉,噁心一點,做個網頁,讓民眾回報購買通路價格,做成歷史價格,用市場來打市場
要控制購買,要有手段能控制,健保卡,各通路會員制


想想這事還真的很難辨,照上做了,肯定又會發現上面的做法會有問題產生... 哈


==========

看大陸官方的說明比較準,之前說封城,實際上它的意思不是封城,是管制,我看繁華十年,實際上只要真的有親人,有人擔保,還有進入後隔離,就能進入了

致死率 妳如果有看我轉的論文,妳會發現
有的省份死亡率高到30%,大部份都是10%
我不知道我有沒有看錯
看29頁的圖,就會知道中獎和死亡 除非我搞錯意思
https://www.medrxiv.org/content/10.1101/2020.02.06.20020974v1.full.pdf

隨時都在變異,論文中提到的 超級感染者,這才是最可怕的

我到不覺得 一開始跟時間賽跑這個東西,我看AKA說的很清楚,我也非常能認同, 當疾症發生時,絕對不是看到黑影就開槍,實際上經過sars後,大陸已經有一套做法了,早已改了很多法令,為了這種情況,早在李文景發聲前,中國官方機構早就發現異常,但絕對不是我們想的,因為這個狀況從現在看來,從論文看來,很早就感染,而且不發燒,沒症狀,也能傳染,這怎麼防護?就算那時候用SARS的規格來防,沒用啊!因為沒發燒啊!連檢查ct都可能沒有異狀,看的越多越會覺得這個病很皮!

我都不看台灣報導,只看中國官方,然後結合yb上的相關內容,去掉 “情緒“ 來看,自然看的清,像妳剛說的,屍體燒不完,我大概都有看到新聞,我都直接略過,內容都懶得看了! 這種 屍體燒不完 ,大概就像我們sars時,我們彰化也在傳,那醫院半夜都有人進進出出一樣...呵呵

屍體燒不完 如果是真的話,香港、台灣早就也跟著燒不完了,因為 論文已經說的很明白了,沒有症狀!沒有症狀也能感染啊!連檢查都可能查不出來,怎麼防止!


年輕人不就醫也沒事的
最近看一個大陸yb,她老婆中獎,他自己照顧她老婆,應該撐過去了
https://youtu.be/9LOn5iBWRdc
還是不行,要住院

==========


https://www.youtube.com/watch?v=b-Fy80yHYQo

https://www.youtube.com/watch?v=_ZijOuFySgg


https://www.facebook.com/931837986851749/posts/2734799916555538/

https://www.facebook.com/931837986851749/posts/2736794659689397/


https://youtu.be/A75ivAVd-M0?t=1642
呵~~ 像候漢廷 fb的內容

>> 提高口罩的價格,才能阻卻不必要的搶購。才能促使商家願意增產。政府統一收購為0.94元,最終售價為8、6、5元,何來誘因使商家拚命生產?
>> 台灣所有口罩由政府統一收購,價格不高,阻卻商人販售回台。縱使事先即有執照者,同樣一批口罩,大陸售價高,台灣售價低,自然多數販售給大陸。
>> 無法轉賣毫無利潤,僅憑企業慈悲,難解問題。而國際代購業者售價必然高於台灣法定價格,台企業要嘛放棄購買,要嘛轉手倒賣。


https://youtu.be/KvcOb3bY9zk?t=337
大陸VS台灣領取口罩大PK|寒國人 底下討論也非常值得一看


韓國管制使用app 自主回報 還用app的gps來追
https://youtu.be/I2fn5lIM3ec?t=190 韓國用app回報


大陸買口罩的方式
https://www.youtube.com/watch?v=KvcOb3bY9zk&feature=youtu.be&t=337

===== 次氯酸水 =====



次氯酸VS漂白水 兩者一樣嗎?
「次氯酸HOCl」與「漂白水NaOCl」常被認為是相同的物質,但實際上他們是具有非常不同性質的兩種成分,現在就讓白博士來為大家解惑。

首先讓我們先來看一下化學式,雖然同樣具有「氧」和「氯」,但只要換了其中一個元素,如從「氫」變成「鈉」,就完全是另一個成分了。

以「酸鹼度」來看,次氯酸HOCl是弱酸性(pH<7);而漂白水NaOCl是鹼性(pH>7)。
殺菌能力就更不用說了,在相同濃度下,次氯酸HOCl的殺菌能力是漂白水NaOCl的100倍以上。

所以次氯酸與漂白水是看似相同卻是非常不同的成份。

http://www.honova.com/sabre.htm

https://www.youtube.com/watch?v=rRfmAMG5JBo

https://professorlin.com/2020/02/17/%E5%86%A0%E7%8B%80%E7%97%85%E6%AF%92%E6%9C%89%E5%A5%97%E8%86%9C%EF%BC%8C%E6%89%80%E4%BB%A5%E6%AC%A1%E6%B0%AF%E9%85%B8%E6%B0%B4%E7%84%A1%E6%95%88%EF%BC%9F/

====== =====
#武汉肺炎Q&A
#冠狀病毒 #CoronaVirus

感恩 抽空为我们解答

Q: #我需要戴口罩吗?
🅰普通口罩无法过滤病毒。如果你没有生病不需要戴口罩。但如果生病了就应该戴口罩,这样打喷嚏或者咳嗽的时候口水才不会到处飞。其实戴口罩不是为自己而是为别人戴。请把口罩让给真正需要的人。

Q:#遇到咳嗽的人立刻暂时停止呼吸、#马上远离有用吗?
🅰我们来不及提前知道他们几时要咳嗽打喷嚏,所以一旦他们突然打喷嚏咳嗽的时候,细菌病毒就马上到处飞,进入我们的鼻子/眼睛/嘴巴,感染我们的呼吸道。就算不呼吸/逃跑也是没用的。

Q:#此病毒存活可以多久?
🅰科学家还不知道它可以在表面上活多久。但是我们看普通的感冒病毒它能够在表面上活几个小时,如果我们打喷嚏在手上,过一个小时我们手上的病毒有可能感染别人。但也要看湿度,如果表面比较干,病毒会活得比较短。如果表面比较潮湿比如有口水/鼻涕,病毒就会活得比较久。

Q:#干洗手消毒凝胶VS肥皂水哪一个比较好?
🅰肥皂水更快更方便因为只需要20秒就可以把全部病毒给毁灭掉。但是在外不方便的话,用干洗手消毒凝胶的时候确保手是干的才有效,如果手湿湿的话,那些流感病毒有可能不会被毁灭掉。如果要把所有病毒给毁灭掉就要等4分钟,才会把病毒给完全毁灭掉。

Q:#家中的宠物会感染2019新冠状病毒吗?
🅰狗/猫不会被感染,也不会传播给人。最近没有报告显示狗/猫传染给人。

Q:#我会因为来自中国的物品而被感染吗?
🅰不会。因为病毒不会在包裹上活得那么久,而且也没有报告显示有人因为包裹而受感染。

Q:#低温利于病毒存活?#所以天气越温暖越有利疫情控制?
🅰病毒不喜欢热,遇到60多度就会死亡,遇到潮湿空气就会变重掉下来不会漂浮在空气。所以马来西亚的天气比较不利于病毒的传播。

Q:#2019新冠状病毒与其他大规模爆发性传染病的比较
🅰死亡率只有2%。比其他的爆发性传染病低很多,所以不必担心,很多人都开始慢慢痊愈。此疾病死亡的人都是因为年纪比较大/有其他疾病比如心脏病或肺部疾病,他们的免疫力比较弱,所以比较难康复。

Q: #有疫苗可以帮助这个病毒吗 ?
🅰很难有疫苗因为它突变太快了
(科学家已发现病毒在变异了)

Q: #空气清净机可以过滤病毒吗❓
🅰不能,因为病毒是很小很小的

**以上资料来自 讲座笔记

flutter build release

https://medium.com/flutterpub/flutter-andorid-keystore-path-on-different-os-d0fc30a24d4f

https://blog.csdn.net/joye123/article/details/94588949


signingConfig signingConfigs.release

Important is signingConfig signingConfigs.debug -> signingConfig signingConfigs.release




    signingConfigs {
       release {
           keyAlias keystoreProperties['keyAlias']
           keyPassword keystoreProperties['keyPassword']
           storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
           storePassword keystoreProperties['storePassword']
       }
    }
    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.release

            minifyEnabled true
            useProguard true
        }
    }
}

flutter create project name com.xxx.xxx

https://stackoverflow.com/questions/51534616/how-to-change-package-name-in-flutter
https://medium.com/@skyblazar.cc/how-to-change-the-package-name-of-your-flutter-app-4529e6e6e6fc



EDITED : 27-Dec-18

for package name just change in build build.gradle only


defaultConfig {
    applicationId "your.package.name"
    minSdkVersion 16
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}



flutter create --org com.yourdomain appname

golang loggin gin

https://github.com/uber-go/zap

https://marcoma.xyz/2019/03/17/gin-tutorial-7/

https://github.com/natefinch/lumberjack

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

function widget or widget StatelessWidget

https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/644148/

拆分widget

永遠不要使用方法返回的形式創建可重用的widget,始終將它們封裝到StatelessWidget中。 注意這個結論中的可重用。

[轉]职场困惑:我该怎么办?

https://www.v2ex.com/t/637213 這討論蠻不錯的


看了楼主的回复,我觉得你存在一个非常典型的思维方式: 我自己称为借斧子(参考这个里面的第一个故事: http://news.sina.com.cn/o/2018-01-07/doc-ifyqiwuw7820642.shtml )
很多人喜欢猜,猜别人的想法,别人的动机,给自己预设很多条件,然后在这个限制中拼命挣扎。无论你怎么去预设你老大的思维,都不及你去和他当面深入交流一下。无论结局如何,聊完,你基本上可以获得你想要的答案:
1. 如果老大告诉你绩效 B 的原因: 这个最好
2. 老板告诉你一个你不能接受的原因: 你们经过争论是否能统一思想,如果不能,说明你和老大思路不和,要不改变自己,要不就换个老大
3. 老大不告诉你: 说明你不可能拿到 A 了,你该换工作了

最后,注意和老大及时高频率的沟通,注意不是去拍马屁,不是去出风头,而是去实实在在的沟通工作内容,任何工作相关的东西都可以,保持几天一次一对一沟通的频率,能够让你和老大的关系提升许多。不要觉得不想厚黑就不去主动找老大聊工作,没有那么多非黑即白的东西

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

[轉]如何為LINUX, WINDOWS容器加入憑證?

https://blog.kkbruce.net/2020/01/linux-windows-container-add-cert.html?fbclid=IwAR0d_LhzAYwatOZ-Ibl4mK7Ne-iAViwKT_UWcj0Wg52YlHTKzSFNDWcp-Hk#more

ubuntu

/usr/local/share/ca-certificates
update-ca-certificates


windows

Import-Certificate -FilePath ooxx   -CertStoreLocation ooxx


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

修行

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

心自體不可得,作用可得

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

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

跟外境沒有關係

不生滅心

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
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。