consensus and smart contract development

Brief Analysis on Top Tier Blockchain 3.0 Projects

Got you. I think on the latest article by Guo "Dream of Bytemaster? Realized by Ultrain" that's a more update article. It mention how Algorand is forgo the human nature of the blockchain world. I think having a credit system established for node selection would be a good approach to this issue


hacker marathon and regular meetup or online game

Redirect HTTP to HTTPS for whole site?

@gtdzx Thank for your warm heart. I tested the links you providered. It automatically redirect to HTTPS.


Industry dynamics and latest news about blockchain and currency

Too Dull to Mention? The Era of Blockchain 3.0 is coming

Ultrain CEO Guo Rui

Blockchain has been described as a revolutionary technology — that the technology born from Bitcoin will change our lives and guide us towards a future way of living. This hype is somewhat dampened, however, by the disappointing performance of existing blockchain infrastructure. Ever since Ethereum was introduced to the world, Blockchain 3.0 has been the ultimate vision that will fully realize the true value of the Internet. It is widely believed that a virtual business network, perfectly compatible with the concepts of decentralization, security, and ideal performance, will eventually be realized.

We face the blockchain Trilemma, which describes the tradeoff between simultaneously achieving high performance, decentralization and security in a blockchain system. Optimizing this triangle has become the main focus of every public chain project on the market, though limited breakthroughs have been made in recent years.

In a recent interview, Rui Guo, co-founder and CEO of Ultrain, expressed his opinion:
“A lot of us are often too optimistic about the development of technology in the short-run, while remaining pessimistic towards our long term goal.”

Guo stated this with great confidence in the future of blockchain technology, while also pointing out that Ultrain’s founding team “only focuses on the long-term value of blockchain technology… with dedication and commitment, blockchain can establish an innovative trust relationships, and execute transactions that generate great growth to existing enterprises… Such technological value, created to benefit our society, will scale up within three to five years…”

Despite the global crypto bear market, Ultrain received funding from top venture capital investors, concluding a 20 million dollar private round in July, valuing Ultrain at 200 million USD. With laser focus, Ultrain is relentlessly continuing development of its ultimate goal, and achieving new milestones every week.

Ultrain recently announced the official opening of its test network, allowing enthusiastic community members to contribute to the network from early December. DApp developers can already deploy their own Ultrain smart contracts to the testnet, verifying their functionality in a real blockchain environment. Ultrain is proud to be one of the first Blockchain 3.0 project with open test network worldwide.

In light of the latest new progress, Rui Guo would occasionally recall the early days of Ultrain when the company was first formed. In a volatile market, the key to success is to build a company focused on technological evolution, rather than financial speculation. Guo first encountered blockchain in 2012 while working as Technical Director of the Alibaba Security Group, and was immediately curious about the technology. This spark of curiosity quickly ignited into a long term and firey passion, leading Guo to much personal experimentation with blockchain. When the popularity of the burgeoning blockchain industry entered new heights in May 2017, Guo made the decision to deepen his involvement. Using his accumulated expertise in the field, he quickly established a vision for the future development of blockchain that addresses the technical issues currently faced.

Ning Li, working as the Chief Architect of the blockchain team at Ant Financial, hit it off with Rui Guo from the moment they met. Guo and Li decided to form a team and devote themselves to the revolution that is blockchain technology. Guo described the feeling at the time: “… we felt the excitement of an engineer who is eager to resolve technical challenge.”

Such excitement did not blind the duo. After experiencing the exponential growth of Alibaba, Guo and Li recognized the importance of user engagement to a project’s success. Emma Liao, who was head of IoT investment at Qihoo 360 at the time, had the expertise and experience to drive a thriving ecosystem around the project.

Soon after the three met for the first time, Ultrain was formed.

The three entrepreneurs formed a solid and complementary triangular structure, covering each other’s weaknesses and complimenting each other’s strengths. A shared devotion to resolving blockchain’s technical issues, created a simple goal: to building a programmable business society.

From that day, Ultrain was born.

At this point, are public chains too dull to mention?

As an innovator working on the cutting edge, Guo has a nuanced answer to this question. He explains that the approaches existing blockchain projects have to the “blockchain trilemma”, such as DFINITY, Oasis Labs, Algorand, Thunderella, and Zilliqa, can be classified into two groups: generate block prior to confirmation and generate block after confirmation.

An example project of the former solution is DFINITY, and an example of latter project is Algorand. Both projects are well received with great attention.

The solution chosen by Ultrain is logically consistent with Algorand, using a Verifiable Random Function (VRF) and Byzantine Fault Tolerance (BFT) as the core technology. The difference is that Ultrain has achieved further optimization with a self-designed Random Proof of Stake (R-PoS) consensus mechanism, as well as implementing an incentive and punishment mechanism based on token staking. The penalty mechanism increases the cost of a malicious attacks, improving the overall security of the Ultrain network.

Traditionally, the basic VRF+BFT consensus process is as follows:

The first stage is known as the Role Confirmation phase: at the beginning of each round of consensus, each node uses VRF to generate a credential. Nodes with a matching credential are then randomly selected to participate in the current round of consensus. Participants are split in to two groups: Voters and Proposers.

The second stage is the Hierarchical Consensus phase: Proposers are responsible for generating candidate blocks. Blocks are then verified by Voters. Consensus is reached upon by the Voters of this round, and the candidate block is noted as being confirmed.

The third stage is the Binary Byzantine phase: Voters vote on the candidate block, with the option of accepting or rejecting the candidate block if it is considered to have an error, such as double spending. If a block is rejected it is replaced by an empty block.

The fourth and final step is to broadcast the blocks identified in this round to the entire network.

Ultrain's R-PoS algorithm adds an ingenious mechanism to the VRF+BFT system: the Token Deposit Staking Mechanism.

In the first phase, three inputs are made to the Ultrain’s VRF: the number of UGAS stake by a single node, the previous performance rating of the node, credibility of specific machines.

In Ultrain’s R-PoS algorithm, the output of the VRF is used to confirm the roles of:

Proposer node: the node responsible for assembling and generating the candidate block in this round. There will be multiple nodes selected as the Proposer node.

Voter node: responsible for the next stage of voting and to confirm the identity of the Proposer node of each round.

Notary node: Does not participate in the block formation stage, but records block data once a block is generated.

The probability of a single node being selected as a Proposer or Voter node depends mainly on the input parameters of the VRF, as outlined above. The higher the parameter, the higher the probability of being selected. The machine credibility score (determined by a node demonstrating good behavior), as well as the token-based locking mechanism, greatly improves and guarantees the overall security of the Ultrain network. Algorand, which runs on an idealized model that assumes that 2/3 of participating nodes are credible, overlooks the "human nature" components of blockchain, which may limit the projects development.

The Token Deposit Staking Mechanism allows Ultrain to determine the number of nodes participating in a particular round of consensus during the Role Confirmation stage by using the Fisher–Yates shuffle algorithm, where Algorand loses efficiency by electing a consensus committee based on probability.

Ultrain implements another change to VRF+BFT in the second stage, transforming Hierarchical Consensus into a parallel consensus phase. The selected Proposer nodes assemble candidate blocks in parallel, and Voter nodes reach consensus on the Proposer nodes during the current round to determine if the candidate block is accepted by most of the nodes in the network.

Having multiple Proposer nodes generating blocks in parallel improves the overall TPS of the system. In addition, parallelism improves the flexibility of the system. If a Proposer node is under attack, as long as a single node is capable of reaching consensus, the system will not produce an empty block. A parallel BA algorithm is used to overcome the technical challenge of voting on a proposed block, but this may result in network storms.

To solve this problem, Ultrain introduces redundant coding technology to divide the message into multiple transmissions, ensuring that the most messages can be broadcast with limited network bandwidth, optimizing network throughput.

In addition, Ultrain also introduces an aggregate signature algorithm that allows candidate blocks to be delivered in small chunks, meaning each node won’t receive the full block before voting is completed. Hiding the content of the message avoids collusion, improving the overall fairness of the system.

Guo uses a simple comparison: “… picture EOS with their DPoS consensus mechanism as a large group of people voting for a fixed number of people to make decisions for them. The voting decision is based on the number of tokens held by individuals in a large group. In comparison, the R-PoS mechanism randomly selects a few nodes to make the initial block proposals, and then randomly selects 10 times more people to judge and review whether the previous proposal is correct or not.”

The core idea of ​​R-PoS is to change the selection method of participating nodes from a trusted election method, such as DPoS, to a random selection method. This allows any node in the Ultrain network to participate in the consensus process, which not only protects the decentralization of the network, but also greatly improve performance.

Ultrain released the conceptual network of R-PoS in July 2018, deploying 1000 nodes to the AWS cloud. The network was able to reach an average of 3000 TPS with a confirmation time of 10 seconds. This performance far exceeds other existing blockchain 3.0 projects.

Ultrain’s Plan for 2019

When discussing Ultrain’s plan for 2019, Rui Guo said that in addition to the launch of Ultrain's main network at the end of April, Ultrain will deploy wallets, DApps and mining machines within the year. The recent announcement of opening the testnet for public application indicates Ultrain is moving from the theoretical phase to a quasi-realistic scenario. Unlike Ultrain's cloud-based test network, the biggest challenge to a public testnet is the quality of each node, and achieving global distribution. These factors are critical for Ultrain to grow into “the world computer”.

In the face of the deteriorating bear market, Guo believes that the emergence of a killer DApp is of the utmost importance to stabilize the market.

Why hasn't there been a real large-scale commercial blockchain application?

"The blockchain has a huge impact on business scenarios through establishing trust relationships and transactions," Guo said. "We believe that projects in sectors such as fan economies, healthcare, energy, and logistics will benefit from blockchain technology and grow manifold.”

Guo anticipates the successful deployment of Ultrain’s mining rigs will see blockchain technology will be enter people's daily lives within five years.

A technology is called revolutionary when it creates a fundamental change to our society. In Ultrain's perspective, finance, an industry that relies on a well-established trust system, is not the main battlefield for blockchain technology. To Guo, blockchain will greatly contribute to the logistics giants known in China as “Si Tong Ba Da”, and would mark a new chapter in the blockchain industry if adopted.

According to Guo, Baidu, Alibaba and Tencent (aka, BAT) will not be the main players in blockchain. He adds his two cents: “BAT will not be the main character in the blockchain world, they will only be the followers to a leader”

Recently, Ethereum founder Vitalik Buterin has expressed similar views publicly. Buterin believes that the so-called application of blockchain technology in many industries is actually a marketing gimmick.

Guo recalls that during his tenure at Alibaba, the original platform management department played the role of controller, which reflected that BAT's is built on the centralization of control. The underlying premise of blockchain technology is precisely the opposite – decentralization.

This notion of control limits BAT's approach to blockchain technology to micro-innovations, such as the "consortium blockchain". Such micro-innovation may lead to some system optimization, but could not be considered revolutionary.


Dapp develop tools and high-quality application recommendations

How to build an end-to-end DApp on Ultrain - 2

Step2:Write DApp

There are two Dapps to be written, one is MiningDapp, the other is UDapp. We use the Javascript SDK U3.js to write the DApps. To be simple, we create the two DApps in one project.

Written by DApp

In WebStorm, create a new project -> Node.js Express App-> Template select Pug (Jade); modify the project name to CarbonDApp;

Click ‘Create’ to create a project

Import project dependent class library

Copy all the directories in node_modules in CarbonProject to the node_modules directory of CarbonDApp, and repeat the directory skipping without copying;
Copy the CarbonDApp/node_modules/u3.js/dist/u3.js file to the CarbonDApp/public/javascripts directory.

Modify the DApp server port

Since the default 3000 port is already occupied, you need to modify the server port of the DApp.

Open the bin/www file and find var port = normalizePort(process.env.PORT || '3000'); change 3000 to 3001

Create an account information browsing page

Create an index.html page in the public directory and add the following code to the page:

<html> <head> <meta charset="UTF-8"> <title>test</title> <link rel="stylesheet" href="/stylesheets/style.css"> <script src="./javascripts/u3.js"></script> <script> let u3 = U3.createU3({ httpEndpoint: '', httpEndpoint_history: '', broadcast: true, debug: false, sign: true, logger: { log: console.log, error: console.error, debug: console.log }, chainId:'2616bfbc21e11d60d10cb798f00893c2befba10e2338b7277bb3865d2e658f58', symbol: 'UGAS' }); async function getBalanceInfo() { let SYMBOL = 'CARB'; let account = 'ben'; const ben_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: account }); document.getElementById("carbon_balance").innerHTML = '账户余额:'+ben_balance; const bob_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: 'bob' }); document.getElementById("bob_balance").innerHTML = '账户余额:'+ bob_balance; const tom_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: 'tom' }); document.getElementById("tom_balance").innerHTML = '账户余额:'+tom_balance; const tony_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: 'tony' }); document.getElementById("tony_balance").innerHTML = '账户余额:'+tom_balance; const jerry_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: 'jerry' }); document.getElementById("jerry_balance").innerHTML = '账户余额:'+tom_balance; const jack_balance = await u3.getCurrencyBalance({ code:'ben', symbol: SYMBOL, account: 'jack' }); document.getElementById("jack_balance").innerHTML = '账户余额:'+tom_balance; } getBalanceInfo(); //transfer(); </script> </head> <body> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>CarbonCoin发行方</h1> <p>账户:ben</p> <p>描述:进行CarbonCoin发行的发行方,持有所有未分配的CarbonCoin</p> <p id="carbon_balance"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备1</h1> <p>账户:bob</p> <p>描述:通过节能产生CarbonCoin的节能设备1</p> <p id="bob_balance"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备2</h1> <p>账户:tom</p> <p>描述:通过节能产生CarbonCoin的节能设备2</p> <p id="tom_balance"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>航空公司C</h1> <p>账户:tony</p> <p>描述:大型航空公司,化石能源使用大户</p> <p id="tony_balance"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>汽车制造商D</h1> <p>账户:jerry</p> <p>描述:大型汽车制造商,化石能源使用大户</p> <p id="jerry_balance"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>CarbonCoin销毁账户</h1> <p>账户:jack</p> <p>描述:用于CarbonCoin销毁的账户,持有所有销毁的CarbonCoin</p> <p id="jack_balance"></p> </div> </body> </html> Start the DApp service, test the page
In the npm interface, double click the start button

After the server is successfully started, visit and the following page appears:

It can be seen that the issuer ben account holds 10 million of all CARB Tokens issued; other accounts have not yet held CARB Token;

Create a mining.html page

Mining.html page, energy-saving device 1 and energy-saving device 2 send the calorie value generated in the first 30 seconds to the energy smart contract every 30 seconds, and redeem CarbonCoin;

Create a mining.html page in the public directory, enter the following code:

<html> <head> <meta charset="UTF-8"> <title>test</title> <link rel="stylesheet" href="/stylesheets/style.css"> <script src="./javascripts/u3.js"></script> <script> let u3_bob = U3.createU3({ httpEndpoint: '', httpEndpoint_history: '', broadcast: true, debug: false, sign: true, logger: { log: console.log, error: console.error, debug: console.log }, chainId:'2616bfbc21e11d60d10cb798f00893c2befba10e2338b7277bb3865d2e658f58', keyProvider: '5JoQtsKQuH8hC9MyvfJAqo6qmKLm8ePYNucs7tPu2YxG12trzBt',//bob's private_key symbol: 'CARB' }); let u3_tom = U3.createU3({ httpEndpoint: '', httpEndpoint_history: '', broadcast: true, debug: false, sign: true, logger: { log: console.log, error: console.error, debug: console.log }, chainId:'2616bfbc21e11d60d10cb798f00893c2befba10e2338b7277bb3865d2e658f58', keyProvider: '5KXYYEWSFRWfNVrMPaVcxiRTjD9PzHjBSzxhA9MeQKHPMxWP8kU',//tom's private_key symbol: 'CARB' }); function wait(ms = 0) { return new Promise(res => setTimeout(res, ms)); } function randomFrom(lowerValue,upperValue) { return Math.floor(Math.random() * (upperValue - lowerValue + 1) + lowerValue); } async function mining() { let owner_account = 'ben'; const tr_bob = await u3_bob.contract(owner_account); const tr_tom = await u3_tom.contract(owner_account); // let amount = U3.format.UDecimalPad(2000,4); let heat_bob = randomFrom(15000,20000); let heat_tom = randomFrom(15000,20000); await tr_bob.recordHeat(heat_bob,{ authorization: [`bob@active`] }); await tr_tom.recordHeat(heat_tom,{ authorization: [`tom@active`] }); var d=new Date(); var t=d.toLocaleTimeString(); document.getElementById("bob_log").innerHTML = 'time :'+t+', heat value :'+ heat_bob; document.getElementById("tom_log").innerHTML = 'time :'+t+', heat value :'+ heat_tom; } mining(); var int=self.setInterval("mining()",30*1000); </script> </head> <body> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备1</h1> <p>账户:bob</p> <p>描述:通过节能产生CarbonCoin的节能设备1</p> <p id="bob_log"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备2</h1> <p>账户:tom</p> <p>描述:通过节能产生CarbonCoin的节能设备2</p> <p id="tom_log"></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <button onclick="int=window.clearInterval(int)">stop</button> </div> </body> </html>

Go to and the following page appears:

There are two things to note here.

When sending data to the energy smart contract, you need to hold the private key of the account before you can sign and send it. In order to simplify the programming, the private key is directly written to the webpage. In the actual program, the private key needs to be protected and hidden.

To simplify the writing, the Bob and tom DApp programs are written directly to a page. Actually, they should be two DApp program instances, which are running on two devices respectively.

Now our energy-saving equipment can already send data to the smart contract, and after the energy smart contract receives the data, it will pass the data to the operator server, and the operator server will call the energy smart contract again to exchange carboncoin. So we need to establish EnergyServer;

Step3: EnergyServer

Establish event monitor and handle events

In this section, we will deal with the above calorific value data upload event.

1.1 Establish listener event server code

In the bin directory of the CarbonDApp project, create a new file msgBroker.js and enter the following code.

const { createU3 , format} = require('u3.js/src'); const http = require('http'); const port = 3002; let u3 = createU3({ httpEndpoint: '', httpEndpoint_history: '', broadcast: true, debug: false, sign: true, logger: { log: console.log, error: console.error, debug: console.log }, chainId:'2616bfbc21e11d60d10cb798f00893c2befba10e2338b7277bb3865d2e658f58', keyProvider:'5JbedY3jGfNK7HcLXcqGqSYrmX2n8wQWqZAuq6K7Gcf4Dj62UfL',//ben's private key symbol: 'UGAS' }); let server = http.createServer((request, response) => { const { headers, method, url } = request; console.log(method); console.log(url); let body = []; request.on('error', (err) => { console.error(err); }).on('data', (chunk) => { body.push(chunk); }).on('end', () => { body = Buffer.concat(body).toString(); console.log("received msg:", body); if (body != null && body.trim()!="") { var obj = JSON.parse(body); let heatValue = JSON.parse(obj[1]).heat.split(",")[0]; let account = JSON.parse(obj[1]).heat.split(",")[1]; exchangeCarbonCoin(account,heatValue); } response.on('error', (err) => { console.error(err); }); response.statusCode = 200; response.setHeader('Content-Type', 'application/json'); response.write("ok"); response.end(); }); }); server.keepAliveTimeout = 0; server.timeout = 0; server.listen(port, function () { console.log((new Date()) + " Server is listening on port " + port); }); function wait(ms = 0) { return new Promise(res => setTimeout(res, ms)); } async function exchangeCarbonCoin(account,heat) { let SYMBOL = 'CARB'; let code = 'ben'; const tr = await u3.contract(code); let heatValue = format.DecimalPad(heat,4); const result = await tr.exchangeCarbonCoin('ben', account, heatValue+' ' + SYMBOL, 'test', { authorization: [`ben@active`] }); let tx = await u3.getTxByTxId(result.transaction_id); while (!tx.irreversible) { await wait(1000); tx = await u3.getTxByTxId(result.transaction_id); if (tx.irreversible) { console.log(tx); break; } } }

The code establishes a service on port 3002. After the energy-saving device uploads its calorific value, the smart contract will send the energy-saving device to the service to upload the calorific value data. The service calls the exchangeCarbonCoin method of the energy smart contract to exchange the CarbonCoin.

1.2 Establish a listener event server startup script

Open the CarbonDApp/package.json file and add the following code to the scripts property: "event": "node ./bin/msgBroker"

1.3 Start the listening server

Refresh the npm window with the ‘event’ option

Double-click event to complete server startup

1.4 Register event monitoring mechanism on the chain

Query the internal network address of the machine through the ifconfig command, for example:

In the CarbonProject/test directory, create the registerEvent.js file; enter the following code in the file

const U3Utils = require('u3-utils/dist/es5'); const { createU3, format, listener } = require('u3.js/src'); const config = require('../config'); const chai = require('chai'); require('chai') .use(require('chai-as-promised')) .should(); const should = chai.should(); const expect = chai.expect; const assert = chai.assert; describe('Test cases', function() { it('event register', async () => { let account = 'ben'; const u3 = createU3(config); await u3.registerEvent(account, 'http://'); U3Utils.wait(1000); }); it('event unregister', async () => { let account = 'ben'; const u3 = createU3(config); await u3.unregisterEvent(account, ' http://'); U3Utils.wait(1000); }); });

Note that the registered address is modified to be the internal network address of the machine, and cannot be used.
Run the event register test case to complete the event registration;

1.5 Test calorie value for CarbonCoin function

Visit page, every 30 seconds, both bob and tom will randomly send a random value between 15000 and 20000 as the calorific value to convert the smart contract to CarbonCoin;
Visit and refresh the page, you can find that the CarbonCoin account of bob and tom is increasing every 30 seconds;

Step4:Improve DApp functionality

Add transfer function

After the energy-saving equipment acquires CarbonCoin, it can sell CarbonCoin to the enterprise, such as airlines, etc. The simple embodiment is that the equipment account can be transferred to the corporate company account;

Open the /CarbonDApp/index.html page and add the code

1.1 U3 object used when establishing the transfer

let u3_bob = U3.createU3({ keyProvider:'5JoQtsKQuH8hC9MyvfJAqo6qmKLm8ePYNucs7tPu2YxG12trzBt',//bob's private key }) let u3_tom = U3.createU3({ keyProvider:'5KXYYEWSFRWfNVrMPaVcxiRTjD9PzHjBSzxhA9MeQKHPMxWP8kU',//tom's private key })

1.2 Add the js code of the transfer to call the corresponding smart contract method

async function sendCoin(from,to){ let SYMBOL = 'CARB'; let code = 'ben'; let coins = U3.format.DecimalPad(this.randomFrom(100,500),4); if (from == 'bob'){ const tr = await u3_bob.contract(code); const result = await tr.transfer(from, to, coins + ' ' + SYMBOL, 'sendCoin', { authorization: [`bob@active`] }); let tx = await u3_bob.getTxByTxId(result.transaction_id); while (!tx.irreversible) { await wait(1000); tx = await u3_bob.getTxByTxId(result.transaction_id); if (tx.irreversible) { alert("bob send coin success:"+ coins); break; } } } else if (from == 'tom'){ const tr = await u3_tom.contract(code); const result = await tr.transfer(from, to, coins + ' ' + SYMBOL, 'sendCoin', { authorization: [`tom@active`] }); let tx = await u3_tom.getTxByTxId(result.transaction_id); while (!tx.irreversible) { await wait(1000); tx = await u3_tom.getTxByTxId(result.transaction_id); if (tx.irreversible) { alert("tom send coin success:"+ coins); break; } } } }

1.3 Add a call to the sendcoin() method on the page, update the following code

<div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备1</h1> <p>账户:bob</p> <p>描述:通过节能产生CarbonCoin的节能设备1</p> <p id="bob_balance"></p> <p><a href="#" OnClick="sendCoin('bob','tony')">给航空公司C转账</a></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>节能设备2</h1> <p>账户:tom</p> <p>描述:通过节能产生CarbonCoin的节能设备2</p> <p id="tom_balance"></p> <p><a href="#" OnClick="sendCoin('tom','jerry')">给汽车制造商D转账</a></p> </div>

1.4 Access the page and test the function

Visit:, click the "Transfer to the airline C" button, wait for a period of time (up to about 10 seconds, confirm the time for the Ultrain transaction), the following prompt appears, indicating the transfer success.

Add a company to convert CarbonCoin to a charity point function

By converting CarbonCoin into charitable points, the company makes its own contribution to reducing carbon emissions and enhances its reputation:

Open the /CarbonDApp/index.html page and add the code

2.1 U3 object used when establishing point redemption

let u3_tony = U3.createU3({ keyProvider:'5KbHvFfDXovPvo2ACNd23yAE9kJF7Mxaws7srp6VapjMr7TrHZB',//tony's private key }) let u3_jerry = U3.createU3({ keyProvider:'5JFz7EbcsCNHrDLuf9VpHtnLdepL4CcAEXu7AtSUYfcoiszursr',//jerry's private key })

2.2 Add the redeemed js code to call the corresponding smart contract method

async function exchangeScore(account){ let SYMBOL = 'CARB'; let code = 'ben'; let to = 'jack'; let coins = U3.format.DecimalPad(this.randomFrom(10,50),4); if (account == 'tony'){ const tr = await u3_tony.contract(code); const result = await tr.exchangeScore(account, to, coins + ' ' + SYMBOL, 'sendCoin', { authorization: [`tony@active`] }); let tx = await u3_tony.getTxByTxId(result.transaction_id); while (!tx.irreversible) { await wait(1000); tx = await u3_tony.getTxByTxId(result.transaction_id); if (tx.irreversible) { alert("tony buy score success:"+ coins); break; } } } else if (account == 'jerry'){ const tr = await u3_jerry.contract(code); const result = await tr.exchangeScore(account, to, coins + ' ' + SYMBOL, 'sendCoin', { authorization: [`jerry@active`] }); let tx = await u3_jerry.getTxByTxId(result.transaction_id); while (!tx.irreversible) { await wait(1000); tx = await u3_jerry.getTxByTxId(result.transaction_id); if (tx.irreversible) { alert("jerry buy score success:"+ coins); break; } } } }

2.3 Add a call to the exchangeScore() method on the page, update the following code

<div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>航空公司C</h1> <p>账户:tony</p> <p>描述:大型航空公司,化石能源使用大户</p> <p id="tony_balance"></p> <p><a href="#" OnClick="exchangeScore('tony');return false;">购买公益积分</a></p> </div> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>汽车制造商D</h1> <p>账户:jerry</p> <p>描述:大型汽车制造商,化石能源使用大户</p> <p id="jerry_balance"></p> <p><a href="#" OnClick="exchangeScore('jerry');return false;">购买公益积分</a></p> </div>

2.4 Access the page and test the function

Visit:, click the "Buy Charity Points" button, wait for a period of time (up to about 10 seconds, confirm the time for the Ultrain transaction), the following prompt appears, indicating that the points are successfully redeemed. At the same time, you can see the number of CarbonCoins destroyed in the CarbonCoin destruction account at the bottom of the page.

Query the public welfare points exchange history

By enquiring the redemption history of charity points, we can establish a ranking of corporate charity points.

3.1 Creating a page

In the CarbonDApp/public/ directory, create a new leaderboard.html and enter the following code:

<html> <head> <meta charset="UTF-8"> <title>leaderboard</title> <link rel="stylesheet" href="/stylesheets/style.css"> <script src="./javascripts/u3.js"></script> <script> let u3 = U3.createU3({ httpEndpoint: '', httpEndpoint_history: '', broadcast: true, debug: false, sign: true, logger: { log: console.log, error: console.error, debug: console.log }, chainId:'2616bfbc21e11d60d10cb798f00893c2befba10e2338b7277bb3865d2e658f58', symbol: 'UGAS' }); function wait(ms = 0) { return new Promise(res => setTimeout(res, ms)); } async function getLeaderboard() { let owner_account = 'ben'; const tr = await u3.contract(owner_account); const result = await u3.getAllTxs(1,10000000,{"":"exchangeScore"},{_id:-1}); //console.log(result); let content = ''; for ( let i = 0 ;i< result.results.length;i++){ content = content + '<tr><td>'+ result.results[i].actions[0].data.from+":"+result.results[i].actions[0].data.quantity +'</td></tr>'; } document.getElementById("leaderboard").innerHTML = content; } getLeaderboard(); </script> </head> <body> <div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff"> <h1>leaderboard</h1> <table id="leaderboard"> </table> </div> </body> </html>

We use the u3.getAllTxs(1,10000000,{"":"exchangeScore"},{_id:-1}); method to query all redemption transactions and print their specific data to the page.

3.2 Run page

Visit and you can see the following page:

Here is a history of all points redemption.


This tutorial system describes how to write an end-to-end web version of the DApp application. Although it has been simplified in the process of writing, it generally describes the overall picture of DApp application development, developers can do the basis of this framework. Enrich and improve your DApp application.

About developing DApp on iOS and Android, you can integrate u3.js into the corresponding hybrid Native development framework, and the principle is the same as the web version DApp.



走近全球顶级区块链3.0项目 - 著名区块链3.0项目共识分析


Dfinity是2016年在硅谷启动的项目,其创始人Dominic是以太坊早期密码学协会的核心成员之一;Dfinity做出的最突出性的贡献就是将密码学中的门限签名技术引入到共识算法中。Dfinity的共识思路是这样的,首先将全网节点随机分为N组,每轮共识开始时,随机挑选出块节点和见证人节点,出块节点完成出块后,由见证人节点见证选择哪个块做为最终块上链,同时,在出块的过程中也会随机的确定下一个负责出块的出块节点,从而完成共识的继续向下执行。 但是,由于没有POW的算力消耗做为安全保障,为了提升系统的安全性,Dfinity的出块节点和见证人节点并非单一节点,而是节点组。比如其每轮的出块节点就是由400台机器构成的节点组执行出块。而其采用的门限签名技术,保证了一个数据块,被该组中任意超过51%的机器(既超过201台机器)签名后,就可以生成可被外界验证的数据块,同时可以生成用于选择下一轮节点的随机数,通过这种方式,大大的提升了攻击难度,从攻击一个节点,变为了攻击一组节点,提升了系统安全。在密码学领域,VRF(可验证的随机函数,verifiable random functions)是一大类别,门限签名函数是另一大类别,而Dfinity在技术上的最大特点,就是找到了一个同时满足VRF和门限签名特点的函数,保证了其算法可实现。基于该共识,Dfinity对外宣称的是其TPS已达到数百笔/秒左右,每个块的确认时间为7.5秒。

Algorand是图灵奖得主、MIT教授Sivio Micali于2017年5月发布的区块链共识协议,其主要思想是结合随机和BFT算法,在完全去中心化的网络上实现高TPS。
1.第一步,角色确认阶段:对一个大规模网络,每个共识轮次开始时,每个节点先采用VRF(可验证的随机函数,verifiable random functions)生成一个凭证,用该凭证随机选出本轮参与共识的节点,被称为"投票者",而其中凭证值最小的被选为“提议者”
Algorand通过每轮随机选择共识节点的方式,在保障网络安全的基础上,有效提升了系统的TPS,根据其论文给出的数据,可以共识的交易是750M字节每小时,按照比特币每笔交易长度250字节计算:75010241024/60/60/250=873.8 TPS;

Thunderlla的核心创始人是康奈尔大学计算机系教授Elaine Shi。其提出了这样一种新的算法。当网络中加速器(Accelerator)节点和3/4的委员会(committee)节点为诚实节点,并且网络状况比较好的时候,Thunderella可以实现快速异步处理,在<1秒之内做出确认,对交易几乎是瞬间相应。而当网络出现异常时(比如出现了拜占庭将军问题),启动冷却(cool-down)机制,切换到传统区块链共识(慢速链),保证网络的安全和可持续性,并在网络恢复时自动切换回快速模式。由此,可以实现绝大多数时间与情况下,网络超过目前区块链1000倍的处理速度,以及遇到问题时依旧可以通过慢速链抵御49%的恶意节点,这里的慢速链,既可以是比特币,也可以是以太坊,或是其他的区块链一言以蔽之,即友好环境下瞬间响应,恶意环境下安全可靠。

Oasis Lab的Ekiden:基于可信环境的性能提升
该项目是2018年启动的项目,其创始人Dawn Song是加州大学伯克利分校计算机科学副教授。Ekiden的主要思想是将共识层和计算层做了分离;在计算层用符合TEE(可信执行环境,比如Intel的SGX)的硬件组成,智能合约的计算放到 TEE里面去执行,而共识层采用POW或POS,只验证和共识 TEE 计算结果。这种方法有两个特点:1)计算节点和共识节点分开,计算节点里面可以执行任意复杂的逻辑,通过少量的可信计算节点来相互印证计算结果,所以执行效率很高,基本上等效于单机执行效率,然后还能并行多机执行不同的合约;2)隐私保护,链上只存储加密后的数据状态(甚至是加密后的合约代码),解密只在TEE里面完成,然后计算结果从TEE出来后又是加密的回到链上。

目前,zilliqa已经上线了测试网络,同时其透露出的内部网络的测试数据,是在3600台机器上,在6分片的情况下,可以实现TPS 2000笔/秒;




BM 提了个新想法,Ultrain却早已经实现了?

Ultrain CEO 郭睿

前段时间,BM 在 EOS 的电报群抛出了一个关于解决隐私性和性能问题的新想法,总结一下,就是希望通过一种新的设计方法,实现如下几个目标:完全去中心化,任何人都可以跑全节点,同时可以达到千万 TPS;没有 Token 质押和投票;没有 RAM 和 DISK 资源争抢炒作的问题,无需交易手续费。其实这几个目标,也是 EOS 被长期诟病的几个地方,估计也是 BM 一直想去解决的「心病」。

首先,大家都知道 EOS 的共识机制 DPOS 的核心,就是通过每个节点质押的 Token 数量,在一个大规模的网络中选举出 21 个参与共识的节点,由这些节点之间进行共识,达成一致并出块,而不像比特币一样全网出块。EOS 每轮选举出 21 个节点,每 0.5 秒出一个块,3 分钟左右确认该块。据社区最新的 EOS 性能测试报告,其 TPS 约为 3000 笔 / 秒。


一、EOS 的 21 个共识节点都要求极高的机器性能,一个典型的 EOS 共识主节点的配置是 96 核 CPU+256G 内存,机器成本极高,可以视为是网络中的特殊节点,一方面让普通人难以参与到共识节点的建设中,节点数量有限;另一方面中心化的服务器部署很难抵御专业的大规模 DDOS 攻击,这个问题对 Google,Facebook 等互联网巨头来说都是一个棘手的问题,对 EOS 的 21 个节点来说也是一样,黑客可以轻易的通过 DDOS 这 21 个节点,瘫痪该网络;为了解决这个问题,最好的方法就是像比特币或以太坊一样,是一个完全对等的网络,就是网络中所有的机器,在网络中的地位都是对等的,没有类似 EOS 共识节点这样的特殊节点存在,从而人人都有能力可以部署一台全节点机器参与到区块链网络中,实现一个完全的去中心化网络;

二、区块链强调的是完全去中心化和对等的网络,人人在该网络中都是平等的,不存在特殊化,而 EOS 的设计偏离了这种理念,让 21 个节点成为了特殊化节点,而 21 个节点的选择是由质押的 EOS 的 Token 的数量进行投票来决定的,由于成为 21 个节点之一会带来大量的经济利益和好处,EOS 的节点竞选中就难以避免的充斥着贿选,拉票,腐败和串谋,虽然 EOS 的支持者宣称这是性能提升带来的不可避免的妥协,但在区块链行业内对这种妥协并不满意;而解决这个问题最佳的方法,就是彻底取消有人为意志因素的投票方法,取消人为干预;

三、EOS 现在的系统性能,是依赖 21 个节点的系统资源,同时由于区块链的特性,智能合约在运行时需要同时在这 21 个节点上并行运行,所以 EOS 运行的系统资源,主要是 CPU、RAM 和 DISK,是非常有限的,同时 EOS 又不收取代码运行的手续费,为了避免系统资源被无意义的浪费耗尽的问题,EOS 的经济体系是通过抵押 EOS Token 租用系统的 CPU、RAM 和 DISK 资源,这个时候问题就出现了,由于这些资源的总量是有限的,这些稀缺资源立刻导致了投机客的疯狂抢购,现在在 EOS 平台上,1 个日活 1 万的 DAPP,需要抵押的 Token,在现在的币价折合人民币约 350 万元,这远远不是一个普通的 DApp 开发团队可以支付的,从而导致 EOS 平台成为了一个 DApp 应用开发者特别不友好的平台。这个问题是必须解决的,否则除了博彩类的应用开发,其他种类的 DApp 都无法承受这么高的成本在 EOS 平台上运行。

虽然 BM 在 EOS 电报群中只提到了他的设计理念,并没有提具体如何设计,但我们非常欣喜的发现,BM 的设计理念与 Ultrain 在这个方面的设计思考完全一致,而实际上 Ultrain 已经实现了以上三方面的技术设计和实现,这些功能已经在近期上线到 Ultrain 的测试网,并将在 12 月底上线 Ultrain 的准入制主网;

首先,Ultrain 基于自主知识产权的 RPOS 共识机制,在一个完全去中心化的对等网络中已经实现了高 TPS 的设计目标,在今年 7 月 15 日发布的验证网络中,Ultrain 在亚马逊云 1000 个节点上已经实现了 3000TPS,与 EOS 在 21 个节点半中心化条件下到达的 TPS 数值相差无几;Ultrain 网络中的矿机是完全对等的,每台机器都可以是全节点运行。

其次,Ultrain 的 RPOS 共识机制,每轮参与共识的节点是基于 VRF 算法的随机选择,其中抵押的 Token 数量只是 VRF 算法中的一个参数,所以每轮共识节点的选择并不像 EOS 一样依赖于抵押 Token 数量对应投票数量的多少,就可以决定本轮出块的节点;而是一个更加随机的过程,从而有效的避免了投票被操纵的问题,与 BM 提到的没有 Token 质押的投票的思路非常类似。

第三,Ultrain 的经济体系,在设计之初就考虑到如何解决现有区块链经济体系中存在的核心问题:1. 矿工的收益随着全网逐步递减,导致矿机的军备竞赛 2.DApp 开发者的使用费随着使用次数和 Token 价格的增长而增长,而取消使用费会带来有限资源的炒作问题,都会导致 DApp 的运营成本完全无法控制;BM 在这里只提到了第二个问题,我们也先就第二个问题谈谈我们的设计思路。为了解决这个问题,首先需要解决的是系统资源稀缺性的问题,Ultrain 采用了主侧链的设计机制,主链上运行的是 Ultrain 用户的资产信息,而 DApp 应用是运行在每条侧链之上的,主链和每条侧链之间的系统资源都是隔离的,这就保障了系统资源可以无限扩展,在有新的 DApp 需求时扩展一条新的侧链就可以;而这带来的核心设计挑战是安全性的问题,每条侧链的机器数量与全网比起来毕竟是有限的,如何在有限的机器数量下保障侧链的安全性,Ultrain 采用了我们称之为「随机调度」的自主知识产权技术,组成每条侧链的机器并不是固定不变的,这些机器将在一定的时间内在全网机器中随机选择并替换,用动态性和随机性保障系统在去中心化的条件下的安全。在「随机调度」技术的保障下,DApp 的应用开发者在使用 Ultrain 网络时,只需要估算出自己需要使用的资源和时长,付出固定 Token 租用费,就可以使用 Ultrain 网络,更类似于「套餐」制度。

在该设计下,与以太坊 DApp 开发者相比,Ultrain 的 DApp 开发者只需要付出固定的资源租用费租用资源,从而不需要承担 Token 价格上涨带来的成本;而与 EOS 开发者相比,Ultrain 的开发者不会面临资源竞争导致价格高涨的问题,从而保障 DApp 的开发成本完全可控。这里只是介绍了部分 Ultrain 的经济体系,近期我们会撰文详细介绍 Ultrain 的 Token 经济学体系设计。总体来说,非常高兴 Ultrain 在区块链公链设计上的思考能与 BM 一起产生共鸣,也希望有更多的开发者可以试用 Ultrain 的测试网络,请前往 了解更多信息。