Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÔÚ IBM Cloud ÉÏ´´½¨ºÍ²¿ÊðÇø¿éÁ´ÁÄÌìÓ¦ÓÃ
 
  2126  次浏览      27
 2018-11-29
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚIBM£¬±¾ÎÄÖ÷Òª½éÉÜÁËÈçºÎʹÓà Tendermint ºÍ Lotionjs ÇáËɽ«¡°È¨ÒæÖ¤Ã÷¡±Çø¿éÁ´Ó¦ÓÃ×÷ΪÁ½¸öÑéÖ¤Õ߽ڵ㲿ÊðÖÁ IBM ÈÝÆ÷¡£

ǰÌáÌõ¼þ

ÄúÐèÒª°²×°ÒÔÏÂÈí¼þ£º

IBM Cloud CLI£¬ÓÃÓÚ¹ÜÀí IBM Cloud ÖеÄÓ¦Óá¢ÈÝÆ÷¡¢»ù´¡¼Ü¹¹¡¢·þÎñºÍÆäËû×ÊÔ´µÄÃüÁîÐнçÃæ

Docker£¬Ê¹ÓÃÈÝÆ÷¿ª·¢¡¢²¿ÊðºÍÔËÐÐÓ¦ÓÃµÄÆ½Ì¨

Kubectl£¬ÓÃÓÚÔÚ Kubernetes Éϲ¿ÊðºÍ¹ÜÀíÓ¦ÓõÄÃüÁîÐй¤¾ß

±³¾°

Çø¿éÁ´¼¼ÊõÊÇ×Ô´ÓÒòÌØÍøµ®ÉúÒÔÀ´×îΰ´óµÄ¼¼Êõ´´ÐÂÖ®Ò»¡£ÒòÌØÍøÖ§³ÖÐÅÏ¢µÄ×ÔÓÉÁ÷¶¯£¬¶øÇø¿éÁ´ÔòÖ§³Ö¼ÛÖµµÄÎÞÕϰ­Á÷¶¯¡£ÔÚÓ¦ÓÃÃÜÂëѧ·½Ã棬ǰËùδÓеĴóÁ¿Ñо¿ÕýÔÚÈç»ðÈçݱµØÕ¹¿ª¡£¸÷Ðи÷ÒµµÄÆóÒµ¶¼ÔÚ½«Çø¿éÁ´¼¼ÊõÓ¦ÓÃÓÚÕæÊµµÄÒµÎñÓÃÀý¡£

Çø¿éÁ´Ò²ÊÇÒ»Ïîոеļ¼Êõ¡£¿ìËÙ¿ª·¢Çø¿éÁ´Ó¦ÓÃÔ­ÐͲ¢ÔÚÔÆ¶ËÔËÐÐÍùÍùÀ§ÄÑÖØÖØ¡£Tendermint ¿ÉÓÃÓÚ¿ìËÙ´´½¨Çø¿éÁ´Ó¦Óã¬ÒòΪËü¿É´¦ÀíλÓڵײãµÄÇø¿éÁ´²ã£¨ÀýÈç£¬ÍøÂçºÍ¹²Ê¶£©£¬Í¬Ê±»¹¿Éͨ¹ý ABCI£¨Ó¦ÓÃÇø¿éÁ´½Ó¿Ú£©¾Û½¹Ó¦Óò㡣ÔÚ±¾½Ì³ÌÖУ¬ÎÒ½«ÏòÄúչʾÈçºÎʹÓà Tendermint ºÍ Lotionjs ÇáËÉ´´½¨Çø¿éÁ´ÁÄÌìÓ¦Ó㬲¢½«Æä²¿ÊðÖÁ IBM Cloud¡£

ʲôÊÇ Tendermint£¿

¼ò¶øÑÔÖ®£¬Tendermint ÊÇ¿ÉÓÃÓÚÔÚÈκηֲ¼Ê½¼ÆËãÆ½Ì¨ÖÐʵÏÖ°ÝռͥÈÝ´í (BFT) µÄÈí¼þ¡£´Ó¹ÜÀí»ù´¡¼Ü¹¹µ½Éè¼Æ·Ö²¼Ê½Êý¾Ý¿â£¬¶¼¿ÉʹÓà Tendermint¡£Tendermint »ùÓÚÁ½¸öÖØÒªµÄ¼¼Êõ×é¼þ¶ø¹¹½¨£º

¹²Ê¶ÒýÇæ£¨Ò²³ÆÎª Tendermint ºËÐÄ£©¿Éͨ¹ý¡°È¨ÒæÖ¤Ã÷¡±¹²Ê¶È·±£ÔÚÿ̨»úÆ÷Öа´Ïàͬ˳Ðò¼Ç¼ÿ¸öÊÂÎñ¡£

ABCI£¨Ó¦ÓÃÇø¿éÁ´½Ó¿Ú£©Ö§³ÖÒÔÈκαà³ÌÓïÑÔÀ´´¦ÀíÊÂÎñ¡£

Tendermint ¾ßÓÐÒÔÏÂÌØÐÔ£º

°ÝռͥÈÝ´í£ºTendermint ×î¸ß¿ÉÈÝÈÌÈý·ÖÖ®Ò»µÄ»úÆ÷³öÏÖÈÎÒâ¹ÊÕÏ¡£Õâ°üÀ¨Ã÷È·µÄ¶ñÒâÐÐΪ¡£

״̬»ú¸´ÖÆ£ºTendermint ¿É¸´ÖÆÒÔÈκαà³ÌÓïÑÔ±àдµÄÈ·¶¨ÐÔ״̬»ú¡£

°²È«µÄ P2P£ºÍ¨¹ý Tendermint Öо­¹ýÈÏÖ¤µÄ¼ÓÃÜϵͳÀ´±£»¤ Gossip ЭÒéºÍ¶ÔµÈ½Úµã·¢ÏÖ¡£

ÉÁµç°ãµÄËÙ¶È£ºTendermint Ö§³ÖÿÃëÊýǧ¸öÊÂÎñ£¬1000 ºÁÃëÑÓ³Ù¡£

ʲôÊÇ Lotionjs£¿

Lotion ÊÇÔÚ JavaScript Öд´½¨Çø¿éÁ´Ó¦ÓõÄÒ»ÖÖ¿ìËÙ¶øÓÐȤµÄ·½·¨¡£ËüÊÇ»ùÓÚ Tendermint ʹÓà ABCI ЭÒé¹¹½¨µÄ¡£

1ÉèÖÃÏîÄ¿

´´½¨ÐÂĿ¼²¢µ¼º½ÖÁ´ËĿ¼£º

$ mkdir blockchain
$ cd blockchain

°²×°ËùÐèµÄ¿â£º

$ npm i lotion --save
$ npm i dotenv --save

2´´½¨ 2 ¸öÑéÖ¤Õß½ÚµãµÄ˽ÓÐÃÜÔ¿ºÍ´´Ê¼Îļþ

´´½¨´´Ê¼Îļþ£º

touch genesis.json

½«³õʼÄÚÈÝÌî³äµ½ genesis.json ÖУº

{
"genesis_time": "0001-01-01T00:00:00Z",
"chain_id": "name",
"validators": [
],
"app_hash": ""
}

Éú³É 2 ¸öÑéÖ¤Õß½ÚµãµÄÃÜÔ¿£º

$ ./node_modules/lotion/bin/tendermint gen_validator > privkey0.json
$ ./node_modules/lotion/bin/tendermint gen_validator > privkey1.json

˽ÓÐÃÜÔ¿ÀàËÆÈçÏ£¬¹«ÓÃÃÜÔ¿ºÍ˽ÓÐÃÜÔ¿ÊÇËæ»úÉú³ÉµÄ£º

{
"address": "B809574EC51377DE48454094BF3302989CBB50A9",
"pub_key": {
"type": "ed25519",
"data": "8A049817BA6D1B065C30D927A529AAFA7147BE0D147
E1CCD7A25FAADBE80C8D0"
},
"priv_key": {
"type": "ed25519",
"data": "57BAFDD6136E1140FA9F906313BF2CFC75802F044704DD7AAF3
0BC1010E6519C8
A049817BA6D1B065C30D927A529AAFA7147BE0D147E1CCD7A25F
AADBE80C8D0"
}
}

½ö¸´Öƹ«ÓÃÃÜÔ¿ÐÅÏ¢£¬²¢½«ÆäÕ³Ìûµ½ genesis.json ÖС£Ìí¼ÓÁ½¸öÑéÖ¤Õߺ󣬽«ÀàËÆÈçÏ£º

{
"genesis_time": "0001-01-01T00:00:00Z",
"chain_id": "name",
"validators": [
{
"pub_key": {
"type": "ed25519",
"data": "8A049817BA6D1B065C30D927A529AAFA7147BE0D1
47E1CCD7A25FAADBE80C8D0"
},
"power": 10,
"name": "saif"
},
{
"pub_key": {
"type": "ed25519",
"data": "5FD1FBF59759E50BD1C23911E832198AB78A4F7E6F
1F23A64AAFEC5992608CA8"
},
"power": 20,
"name": "prerna"
}
],
"app_hash": ""
}

3¹¹½¨ÑéÖ¤Õß 1

´´½¨ node1 Îļþ¼Ð£º

mkdir node1

ä¯ÀÀÖÁ node1 Ŀ¼£º

cd node1

°²×°ËùÐèµÄ¿â£º

$ npm i lotion --save
$ npm i dotenv --save

½«ÏÈǰÉú³ÉµÄ genesis.json ºÍ privkey0.json ¸´ÖƵ½ node1 Îļþ¼Ð¡£

´´½¨ node1 µÄ»·¾³Îļþ£º

$ touch .env-node1

¶Ô node1.js µÄÄÚÈݽøÐбàÂ룺

LOTION_HOME="./.lotion_node1"

´´½¨ node1.js£º

$ touch node1.js

¶Ô node1.js µÄÄÚÈݽøÐбàÂ룺

require('dotenv').config({path: ".env-node1"});
let lotion = require('lotion')
let app = lotion({
genesis: './genesis.json',
tendermintPort: 30090,
initialState: { messages: [] },
p2pPort: 30092,
logTendermint: true,
keys: 'privkey0.json',
peers: ['workernode2:30092']
})
app.use((state, tx,chainInfo) => {
if (typeof tx.sender === 'string' && typeof tx.message === 'string') {
state.messages.push({ sender: tx.sender, message: tx.message })
}
})
app.listen(3000).then(({ GCI }) => {
console.log(GCI)
})

´´½¨ Dockerfile£º

$ touch Dockerfile

¶Ô Dockerfile µÄÄÚÈݽøÐбàÂ룺

FROM node:carbon
WORKDIR /usr/src/app
COPY package*.json ./
COPY privkey0.json ./
COPY .env-node1 ./
RUN npm install
COPY ..
EXPOSE 30090 30092
CMD [ "node", "node1.js" ]

4¹¹½¨ÑéÖ¤Õß 2

´´½¨ node2 Îļþ¼Ð£º

mkdir node2

ä¯ÀÀÖÁ node2 Ŀ¼£º

cd node2

°²×°ËùÐèµÄ¿â£º

$ npm i lotion --save
$ npm i dotenv --save

½«ÏÈǰÉú³ÉµÄ genesis.json ºÍ privkey0.json ¸´ÖƵ½ node2 Îļþ¼Ð¡£

´´½¨ node2 µÄ»·¾³Îļþ£º

$ touch .env-node2

¶Ô node2.js µÄÄÚÈݽøÐбàÂ룺

LOTION_HOME="./.lotion_node2"

´´½¨ node2.js£º

$ touch node1.js

¶Ô node2.js µÄÄÚÈݽøÐбàÂ룺

require('dotenv').config({path: ".env-node2"});
let lotion = require('lotion')
let app = lotion({
genesis: './genesis.json',
tendermintPort: 30090,
initialState: { messages: [] },
p2pPort: 30092,
logTendermint: true,
keys: 'privkey1.json',
peers: ['workernode1:30092']
})
app.use((state, tx,chainInfo) => {
if (typeof tx.sender === 'string' && typeof tx.message === 'string') {
state.messages.push({ sender: tx.sender, message: tx.message })
}
})
app.listen(3000).then(({ GCI }) => {
console.log(GCI)
})

´´½¨ Dockerfile£º

$ touch Dockerfile

¶Ô Dockerfile µÄÄÚÈݽøÐбàÂ룺

FROM node:carbon
WORKDIR /usr/src/app
COPY package*.json ./
COPY privkey0.json ./
COPY .env-node1 ./
RUN npm install
COPY ..
EXPOSE 30090 30092
CMD [ "node", "node2.js" ]

5½«ÕâÁ½¸öÑéÖ¤Õ߽ڵ㲿Êðµ½ IBM Cloud ÉÏ

×¢²á IBM Cloud¡£

°²×° Cloud Foundry CLI¡£

°²×° IBM Cloud CLI¡£

°²×° Kubernetes CLI¡£

ä¯ÀÀÖÁ node1 Ŀ¼£º

$ cd node1

¹¹½¨ Docker ¾µÏñ£º

$ docker build -t node1 .

תÖÁ IBM Cloud ¿ØÖÆÌ¨¡£

µ¼º½ÖÁ Containers£º Ñ¡ÔñÈÝÆ÷·þÎñ

µ¥»÷ Create Cluster£º ´´½¨Ò»¸öм¯Èº

ÃüÃûÄúµÄ¼¯Èº£¬²¢´´½¨Ò»¸ö¼¯Èº£»µÈ´ý¼¸·ÖÖÓ£¬ÒÔ±ãÍêÈ«²¿Êð´Ë¼¯Èº¡£ÍêÈ«²¿Êðºó£¬µ¥»÷´Ë¼¯ÈºÒԲ鿴ÒѲ¿Êð¼¯ÈºµÄ¸ÅÊö£º ÒѲ¿Êð¼¯ÈºµÄ¸ÅÊö

µ¥»÷×ó²àµ¼º½ÖÐµÄ Access£¬×ñѭָʾÐÅÏ¢½øÐвÙ×÷¡£

°²×°ÈÝÆ÷·þÎñ²å¼þ£º

$ bx plugin install container-service -r Bluemix

µÇ¼µ½ÄúµÄ IBM Cloud ÕÊ»§£º

$ bx login -a https://api.eu-de.bluemix.net
$ bx cs region-set eu-central

ÔÚ CLI ÖÐÉèÖü¯ÈºµÄ»·¾³£º

»ñÈ¡ÉèÖû·¾³±äÁ¿µÄÃüÁ²¢ÏÂÔØ Kubernetes ÅäÖÃÎļþ£º

$ bx cs cluster-config NameOfYourCluster

ÉèÖà KUBECONFIG »·¾³±äÁ¿¡£½«ÏÈǰÃüÁîµÄÊä³ö¸´ÖƲ¢Õ³Ìûµ½ÄúµÄÖÕ¶ËÄÚ¡£

ÁгöÄúµÄ¹¤×÷½Úµã£¬ÑéÖ¤ÄúÊÇ·ñ¿ÉÁ¬½Óµ½×Ô¼ºµÄ¼¯Èº£º

$ kubectl get nodes

תÖÁ IBM Cloud Container Registry¡£

Ñ¡ÔñÊ׸öÃû³Æ¿Õ¼äµÄÃû³Æ£¬²¢´´½¨¸ÃÃû³Æ¿Õ¼ä¡£

$ bx cr namespace-add <my_namespace>

½«±¾µØ Docker ÊØ»¤³ÌÐò¼Ç¼µ½ IBM Cloud Container Registry ÖУº

$ bx cr login

Ñ¡Ôñ´æ´¢¿âºÍÓÃÓÚʶ±ð¾µÏñµÄ±êÇ©¡£ÔÚ±¾½Ì³ÌµÄÆäÓಿ·ÖʹÓÃÏàͬµÄ´æ´¢¿âºÍ±êÇ©¡£

$ docker tag node1 <registry>/<my_namespace>/node1:latest

ÍÆË;µÏñ¡£

$ docker push <registry>/<my_namespace>/node1:latest

ÑéÖ¤ÄúµÄ¾µÏñÊÇ·ñλÓÚ˽ÓÐ×¢²á±íÖУº

$ bx cr image-list

¼ÈÈ»ÄúµÄÈÝÆ÷ÒѲ¿Êðµ½ IBM ÈÝÆ÷ÉÏ£¬ÊÇʱºòʹÓà Kubernetes À´ÔËÐÐһЩ pod ÁË¡£ ʹÓø´ÖÆ/Õ³Ìû½«¾µÏñÃû³Æ´Ó×¢²á±íµÄ˽ÓÐÃû³Æ¸ü¸ÄΪÆäËûÃû³Æ¡££¨Î»ÓÚ service-deployment.yml ÎļþÖеľµÏñÊôÐÔ½«Óë˽ÓÐ×¢²á±íÖеľµÏñÃû³ÆÏàͬ¡££©

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tendermintnodeone # give any name
spec:
replicas: 1
template:
metadata:
name: tendermintnodeone
labels:
run: tendermint1
spec:
containers:
- name: saif1cluster
image: "<registry>/<my_namespace>/node1:latest" # your registry name
imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: my-service-tendermint-11 # give a service name
labels:
run: tendermint1
spec:
type: NodePort
selector:
run: tendermint1
ports:
- protocol: TCP
name: tendermint1
port: 30090
nodePort: 30090
- protocol: TCP
name: port
port: 30092
nodePort: 30092

ÅäÖà Kubernetes ÒÔ´´½¨ pod¡¢·þÎñºÍ²¿Êð£º

$ kubectl create -f service-deployment.yml

ɾ³ýËùÓв¿Êð£º

$ kubectl delete deployments --all

ɾ³ýËùÓзþÎñ£º

$ kubectl delete services --all

·ÃÎÊ pod ºÍÈÕÖ¾£º

$ kubectl get pods
$ kubectl logs podname

·ÃÎÊ Tendermint RPC API£ºhttp://workerip:30092

¶Ô node2 ÖØ¸´ÏàͬµÄ²½Öè¡£

6´´½¨ÇáÁ¿¼¶¿Í»§¶ËÒÔÔÚÇø¿éÁ´ÉÏÖ´ÐжÁ/д²Ù×÷

°²×° lotion-connect£º

$ npm install lotion-connect --save

´´½¨ write.js£º

$ touch read-write.js

¶Ô read-write.js µÄÄÚÈݽøÐбàÂ룺

let { connect } = require('lotion-connect')
async function main() {
let { state, send } = await connect(null, {
genesis: require('./genesis.json'),
nodes: [ 'ws://wordernode1:30092','ws://wordernode2:30092' ]
})
console.log(await state)
console.log(await send({ "sender": 'saif',"message":"himom" }))
process.exit();
}
main()

½áÊøÓï

Tendermint ±ãÓÚÒµÎñ¿ª·¢ÈËÔ±±àÐ´Çø¿éÁ´Ó¦Ó㬶ø IBM Cloud Ôò¼ò»¯ÁË´ËÀàÓ¦ÓõIJ¿ÊðºÍ²Ù×÷¡£

 

   
2126 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ÔÆ¼ÆËãµÄ¼Ü¹¹
¶ÔÔÆ¼ÆËã·þÎñÄ£ÐÍ
ÔÆ¼ÆËãºËÐļ¼ÊõÆÊÎö
Á˽âÔÆ¼ÆËãµÄ©¶´
Ïà¹ØÎĵµ

ÔÆ¼ÆËã¼ò½é
ÔÆ¼ÆËã¼ò½éÓëÔÆ°²È«
ÏÂÒ»´úÍøÂç¼ÆËã--ÔÆ¼ÆËã
ÈídzÎöÔÆ¼ÆËã
Ïà¹Ø¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
ÔÆ¼ÆËãÓ¦ÓÃÓ뿪·¢
CMMIÌåϵÓëʵ¼ù
»ùÓÚCMMI±ê×¼µÄÈí¼þÖÊÁ¿±£Ö¤