consensus and smart contract development

Ultrain Launches Enterprise Mainnet Monitoring & Round Two of Testnet Participant Selection
R

Dear Ultrain community members,

We are excited to announce the launch of Ultrain’s mainnet monitoring page! Click the following link to see the operational status of our permitted mainnet including mining profitability, real-time consensus visualization, and existing mainnet users: https://www.ultrain.io/miner-registration

The addition of this visibility feature will further explain Ultrain’s consensus procedure and business model. Please visit the Mainnet Monitoring service (link provided above) and read the supporting article at https://medium.com/ultrain-chain/introduction-to-ultrains-economic-model-74920e1c687f. These resources assist us to comprehend Ultrain’s token economic system, and understand how Ultrain’s model is based on a notion of servicing and empowering the fundamentals of the real economy.

Ultrain business development model is dependable and scalable; as the demand for blockchain services increases, Ultrain’s economic system will grow accordingly to meet the interests of early adopters, as well as ensure the healthy development of the entire business ecosystem.

Since the call went out for Ultrain’s second round of testnet miner recruitment, we received many applications from all over the world. Thank you all once again for the great interest!
The following is the list of successful applicants – welcome to the Ultrain testnet family and enjoy your preview of Ultrain’s technology.

1、[email protected]
2、[email protected]
3、[email protected]
4、[email protected]
5、[email protected]
6、[email protected]
7、[email protected]
8、[email protected]
9、[email protected]
10、[email protected]
11、[email protected]
12、[email protected]

(The list below represents the selected miners since December 26 2018 to January 13,2019)

Ultrain encourages everyone to continue submitting testnet applications, and stay tuned for more updates from the team!

Thank you all for your continued support of Ultrain.

Ultrain Team
2019. January 25th

read more

hacker marathon and regular meetup or online game

Ultrain.io hacked by Great Security [A3-Sensitive Data Exposure]
T

Hi guys!
Your website, databases and apps was hacked ¯_(ツ)_/¯
https://ultrain.io/trends-detail/B1T5aj1X7

We are not black hat and don't delete anything. We don't use it or sell it on black market.

But we take part in your hackathon =)))) And take the first prize for this vulnerability, which are threat for all your systems.

Pls contact us: great.security[@]protonmail.com!

read more

Industry dynamics and latest news about blockchain and currency

Ultrain’s Random Number Generator Certified by US Authority
R

The importance of random numbers

It is well known how random number generators play an important role in the blockchain ecosystem, requiring random number services that are safe, unpredicable and reliable. Exisisting public chains such as EOS have provided random number services in the past, but often attacked by hackers due to unproperly design.

Ultrain designed a new random number generator architecture to solve this problem, providing service to both consensus and Dapps. So how does Ultrain guarantee the security and randomness of the random numbers on the chain? The answer lies in the following two mechanisms:

The process of generating random numbers is fully decentralized and open to all, so that everyone can participate in generation and verification, while ensuring the minimum probability of manipulation by carefully designing the incentive mechanism.
The result of the random number passes the highest level of cryptographic randomness check: The National Institute of Standards and Technology SP800-22 test. This result indicates that no one can predict any of the future random numbers, with the random result able to be used directly. No additional processing is required, such as increasing entropy.
To further explain point one: verifiable random function is used to compute a random number, which the blockchain verifies and aggregates to generate the final result. This mechanism is enhanced with high penalties and a reasonable incentive model to prevent malicious behavior.

Secondly, Ultrain’s random number process passes the NIST SP800-22 random number test. This certification is the most strict random test in the industry, used to be a requirement for traditional financial transactions and information communication, guaranteeing the security and randomness of the many services built on top of Ultrain.

Lets explore the specific content of the NIST SP800-22 test:

This test includes 15 different sections as follows:

Frequency Test and Block Frequency Test

These two tests count a random number of binary digits. If one of the numbers is obviously more than the other, then the test will not pass. The test checks any sequence of length M for the sequence. If there are any discrepancies the test will not pass.

Run test and Longest Run test (continuous 0/1 test)

These two tests will count consecutive sequences of binary. Strings that do not conform to statistical characteristics are considered to fail the test. The Longest Run test counts the longest 0 or 1 in any specific sequence of arbitrary length. Demonstrating results outside of the standard distribution will fail.

Binary Matrix Rank Test

The entire sequence is divided into several non-adjacent sub-matrices, and then the order of the matrix is ​​tested. The purpose of this test is to find out if there is a correlation in the sequence. That is, whether other sequences can be inferred by another sequence, which would seriously affect the predictability of random numbers.

Discrete FFT Test

Certain sequences can sometimes appear too often, such as 01011. If there are too many instances of this sequence, it will allow attackers to predict future outcomes. For example, after 0101 appears, the next bit is more likely to be 1. This test performs a discrete FFT transformation of the sequence into the frequency domain and then observes if there is a specific number will appear with an abnormal peak.

Non-overlapping/overlapping Template Matching Test (overlap or non-overlapping template test)

The test moves the window one bit at a time to find a periodic or non-periodic sequence. Generally, it is possible to traverse all possible length of sequence at a certain length. For example, for a width of 4, a total of 16 types of 0000, 0001, 0010, …, 1111 can be found. If any one of the frequencies is abnormal, it will fail.

Universal Statistical Test

The test is made by compressing a specific sequence. If a specific sequence can be compressed to a shorter extent, then the sequence itself is redundant and autocorrelated, which is predictable, so it cannot be considered random.

Cumulative Sums/ Random Excursion (Variant) test

If 0 is regarded as -1, then starting from 0 o’clock, left and right, such as 010 is equivalent to walking to -1. This series of tests will study the maximum length of any sequence walked, and the frequency of staying at the point where the walk passes. Any situation that does not match the statistics will fail.

Ultrain random number testing results

1.21 million data points were collected from the Ultrain random number generator, and then binarized to form binary data such as the following sequence:

1000011010001010001100000010001101011000100010101110101110001000

0101000001000010111101100111111110101011001011011111010101101000

0010111010001100100111000001010111110101110110110111111101001011

0111101001001001111100110010110100011101111001100010001100100000

1111011110101110010110110000111001011110101111101001000010000100

0110110111000111111100100101010111011011110101011110010000011100

RESULTS FOR THE UNIFORMITY OF P-VALUES AND THE PROPORTION OF PASSING SEQUENCES

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

generator is<data/sp800test.log>

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

C1 C2 C3 C4 C5 C6 C7 C8 C9C10 P-VALUE PROPORTION STATISTICAL TEST

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

3 7 6 9 8 5 6 10 4 6 0.602458 64/64 Frequency

8 7 7 6 3 4 7 5 6 11 0.568055 63/64 BlockFrequency

3 7 6 6 7 11 9 4 5 6 0.500934 64/64 CumulativeSums

4 8 10 9 4 7 5 7 7 3 0.500934 64/64 CumulativeSums

6 4 8 8 6 5 5 7 5 10 0.804337 63/64 Runs

10 4 6 10 8 1 5 6 9 5 0.178278 63/64 LongestRun

3 7 7 8 2 6 10 6 7 8 0.468595 64/64 Rank

4 9 13 4 7 5 4 11 6 1 0.015963 64/64 FFT

10 8 7 6 8 5 5 7 4 4 0.739918 63/64 NonOverlappingTemplate

9 4 5 7 9 9 6 5 7 3 0.602458 64/64 NonOverlappingTemplate

6 8 3 16 7 5 6 5 4 4 0.014216 62/64 OverlappingTemplate

8 2 5 8 9 4 9 6 6 7 0.534146 64/64 Universal

4 5 6 7 9 7 6 7 5 8 0.931952 63/64 ApproximateEntropy

6 4 5 3 8 5 3 4 3 3 0.689019 43/44 RandomExcursions

6 2 4 5 4 4 3 6 6 4 0.875539 43/44 RandomExcursions

10 4 4 5 8 7 12 5 5 4 0.213309 62/64 Serial

10 8 7 6 7 3 5 7 5 6 0.772760 63/64 LinearComplexity

For each test case, a pass rate of 60/64 and 41/44 was achieved, which means that it passed all tests.

All test data has been uploaded to Ultrain’s Github library(https://github.com/wanghs09/randgen), so anyone can repeat the test. In addition, Ultrain will display the random number in the near future via Ultrain.io. Anyone will be able to generate their own random number data set from Ultrain through this webpage and repeat the test.

Conclusions

Passing the NIST SP800–22 test demonstrates that Ultrain’s random number generator is safe, reliable, and sufficiently random. This also implies that all random numbers generated by the service can be used without additional processing, since they already guarantee enough randomness. Soon, everyone will be able to generate random numbers of the same security level, thanks to Ultrain.

Ultrain continues its work with partners to apply random numbers in the blockchain industry, contributing to fairness and security for all.

read more

Dapp develop tools and high-quality application recommendations

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

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: 'http://127.0.0.1:8888', httpEndpoint_history: 'http://127.0.0.1:3000', 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 http://127.0.0.1:3001/index.html 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: 'http://127.0.0.1:8888', httpEndpoint_history: 'http://127.0.0.1:3000', 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: 'http://127.0.0.1:8888', httpEndpoint_history: 'http://127.0.0.1:3000', 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: [`[email protected]`] }); await tr_tom.recordHeat(heat_tom,{ authorization: [`[email protected]`] }); 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 http://127.0.0.1:3001/mining.html 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: 'http://127.0.0.1:8888', httpEndpoint_history: 'http://127.0.0.1:3000', 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: [`[email protected]`] }); 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: 10.20.8.32

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:// 10.20.8.32:3002'); U3Utils.wait(1000); }); it('event unregister', async () => { let account = 'ben'; const u3 = createU3(config); await u3.unregisterEvent(account, ' http:// 10.20.8.32:3002'); U3Utils.wait(1000); }); });

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

1.5 Test calorie value for CarbonCoin function

Visit http://127.0.0.1:3001/mining.html 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 http://127.0.0.1:3001/index.html 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: [`[email protected]`] }); 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: [`[email protected]`] }); 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: http://127.0.0.1:3001/index.html, 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: [`[email protected]`] }); 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: [`[email protected]`] }); 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: http://127.0.0.1:3001/index.html, 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: 'http://127.0.0.1:8888', httpEndpoint_history: 'http://127.0.0.1:3000', 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,{"actions.name":"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,{"actions.name":"exchangeScore"},{_id:-1}); method to query all redemption transactions and print their specific data to the page.

3.2 Run page

Visit http://127.0.0.1:3001/leaderboard.html and you can see the following page:

Here is a history of all points redemption.

Summary

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.

read more

讨论共识算法、经济模型以及智能合约的开发

Ultrain商用主网监控页面上线 &第二期测试网矿工入选名单公布
R

尊敬的社区成员们:

感谢大家一直以来对于Ultrain的支持!Ultrain正式宣布:商用主网监控页面已上线,各位可通过此页面https://www.ultrain.io/miner-registration查看商业主网的运行数据,了解Ultrain的共识规则和商业模式,并可结合此文https://www.ultrain.io/trends-detail/rk0uOe0gN充分了解Ultrain Token经济体系,明白Ultrain的经济模型建立于服务实体经济的基础之上,是一个更为良性和符合商业发展规律的模型。随着算力购买的商业需求的增长,Ultrain经济体系将会良性发展,保证早期进入者的利益,从而也可以保证整个商业生态的健康发展。

此外,继1月8日发布第二期测试网矿工招募公告后,我们再次收到了大量来自全球各地的申请信息,再次感谢大家对于Ultrain的大力支持,Ultrain于此正式宣布第二期测试网入选名单,欢迎各位加入Ultrain测试网络,提前预览Ultrain技术概貌:

1、[email protected]****.com

2、[email protected]****.com

3、[email protected]****.com

4、[email protected]****.com

5、[email protected]****.com

6、[email protected]****.com

7、[email protected]****.com

8、[email protected]****.com

9、[email protected]****.com

10、[email protected]****.com

11、[email protected]****.com

12、[email protected]****.com

(以下为Ultrain2018年12月26日-2019年1月13日的测试网矿工排名)

欢迎有意向者继续参与我们的下期测试公网矿工申请,也请大家保持对于Ultrain的关注!

ULTRAIN TEAM

2019年1月24日

read more

黑客马拉松与经常性的线下见面会或在线趣味游戏

Ultrain大学派·重庆站
B


read more

关于区块链与币市的行业动态与最新消息

微软销售网络推出首个区块链合作项目——Ultrain 超脑链
R

日前,微软销售网络推出其首个区块链合作项目——Ultrain 超脑链。

即日起,微软将对外正式销售 Ultrain 信任计算企业服务,以其庞大的销售团队在其巨大的全球客户群体中销售 Ultrain 信任计算服务,使其成为 Ultrain 的付费用户。与此同时,微软将对于成功销售 Ultrain 信任计算服务的销售员给予可观的补贴,以此进一步激励其销售 Ultrain 的服务,让 Ultrain 更好更快地服务更多企业。

Co-selling with Microsoft 是微软一项协作销售计划,旨在推动微软合作伙伴获得更多客户,创造联合收入,达成共赢。通过入驻微软销售网络,Ultrain 可得到微软各专家的协助,并借助微软长期而深厚的客户网络、广阔的合作伙伴生态圈及多达 4 万人的庞大销售团队,更好地拓展全球市场。


Co-Sell 计划中的合作伙伴发展趋势

这一步,代表了 Ultrain 信任计算企业服务崭新格局的到来!就让我们共同期待,未来 Ultrain 信任计算服务被广泛地应用在全球各行各业,让更多的商业应用落地变成现实。

详情请查看:https://market.azure.cn/zh-cn/marketplace/apps/ultrain.ultrain?tab=Overview

read more

链上分布式应用的开发工具以及高质量的应用推荐

新版Ultrain浏览器上线,终于可以查Token啦!
I

Ultrain测试网上线后,很多开发者尝试写了合约,并用Ultrain浏览器进行了合约的部署操作。其中最热门的就是发Token合约,大家也想亲身体验发Token的快感!连Ultrain团队的的好几个程序员都迫不及待地进行创建账户、申请资源、写合约、部署合约、调用合约等一系列流程,尝试发Token。

可是操作完,大家向产品经理抱怨:通过「超脑浏览器」对Token合约部署、调用操作之后,在浏览器找不到自己的Token信息。于是产品经理第一时间拉着视觉、开发们,完成了测试网超脑浏览器的Token查询的设计,同时新版的Ultrain浏览器也在很多方面做了优化,继续往下看吧!

1、新增首页数据
打开新版Ultrain浏览器,首页除了全新的视觉设计,一眼就能看到块高、交易数、账户数、合约数、Token数的信息,帮助用户直观地了解超脑链最新数据。

2、Token查询
部署完Token合约,直接在超脑浏览器就可以查询到Token信息,超方便啦!

3、查看账户内Token信息
除了Token列表,在自己的账户内也可以查看账户拥有的Token信息啦。不用手动搜索,浏览器自动同步账户内Token信息,很贴心了哦~

4、无线端兼容
新版的整体视觉做了优化,包括列表页、详情页、创建账户流程、合约部署和调用流程等,同时也特别对无线端做了兼容处理,让用户在手机上操作时更舒服。

5、其他
开发还在性能上、缓存策略上进行了优化,使页面加载速度有了明显提升。

Ultrain浏览器的地址(https://explorer.ultrain.io/),你也来试一试吧!有问题的话,可以到开发者门户-论坛(https://bbs.ultrain.io/)给我们留言哦!

read more