Nebulas一个新的JavaScript开发智能合约平台

Nebulas是另一个可以开发智能合约的平台。它提供了一种使用JavaScript开发智能合约的方法,这是一种有趣的替代方案,可替代更为成熟的解决方案,例如以太坊。

我第一次在Reddit上宣读了Nebulas奖励计划,该计划奖励开发人员成功提交dApp(去中心化应用程序)。从Nebulas的白皮书中,我们可以了解团队的动机以及他们为dApp提供搜索引擎和排名算法的目标。听起来很熟悉?让我谷歌那个。哦,这听起来像谷歌。

通过浏览白皮书,你了解到Nebulas认识到“区块链上应用程序的价值衡量”问题以及使用区块链进行升级和升级的平台的难度。

这不是一个评论,我既不想也不想足够的知识来评估这个项目解决的问题,如上所述,是否值得投入你的时间或金钱。我对开发人员的经验,从工程角度提供工具的质量感到兴趣,并了解它与成熟的以太坊相比如何。如果我们的目标是内联的,那么这是一个值得一读的帖子。

以太坊虚拟机和Nebulas虚拟机

一般而言,如果你熟悉以太坊的工作原理,了解Nebulas虚拟机(NVM)以及平台如何工作是轻而易举的。提供的气体本质上绑定了以太坊虚拟机(EVM)和NVM上的计算。交易费用是使用的gas,乘以gas价格。

有两种类型的帐户:外部/非合约帐户和智能合约(相应地用类型87和88表示)。

1
2
3
4
5
6
curl -X POST \
http://localhost:8685/v1/user/accountstate \
-H 'content-type: application/json' \
-d '{ "address": "n1Vg9Ngvi3vXo5f59diW4MK8XXger36weUm" }'

{"result":{"balance":"1000000000000000000","nonce":"0","type":87}}

在当前连接的节点上本地运行的调用是免费的,立即返回值并且不更改区块链状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
curl -X POST \
http://localhost:8685/v1/user/call \
-H 'content-type: application/json' \
-d '{
"from": "n1QA4usgq7sJbcM5LEkJWpgyNBcKtVEULFf",
"to": "n1mQoB6HneRuu7c15Sy79CPHv8rhkNQinJe",
"value": "0",
"gasPrice": "1000000",
"gasLimit": "2000000",
"contract": { "function": "myView", "args": "[100]" }
}
'

{
"result": {
"result": "{\"key\":\"value\"}",
"execute_err": "",
"estimate_gas": "20126"
}
}

每笔交易都会耗费gas并改变区块链状态(在撰写本文时,它的价格便宜且只占一小部分)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
curl -X POST \
http://localhost:8685/v1/admin/transactionWithPassphrase \
-H 'content-type: application/json' \
-d '{
"transaction": {
"from": "n1Vg9Ngvi3vXo5f59diW4MK8XXger36weUm",
"to": "n1gQgDb72yL1vrRcUEP3219ytcZGxEmcc9u",
"value": "0",
"nonce": 59,
"gasPrice": "1000000",
"gasLimit": "2000000",
"contract": { "function": "myMethod", "args": "" }
},
"passphrase": "passphrase"
}
'

{
"result": {
"txhash": "36a61c6413e71387f34b0b442e73d2a8b54646917c58338166b0473292c0b26d",
"contract_address": ""
}
}

最明显的区别是用于开发智能合约的编程语言。在EVM上,Solidity是编写智能合约的事实上的标准语言。在目前的形式中,NVM支持JavaScript(v8 6.2,从我发现的内容)和准TypeScript,虽然编译为JS。没有可用于存储,交易或其他全局可用对象的类型。

由于支持LLVM的计划,我们可能会看到更广泛的受支持语言,例如C/C++,Go,Solidity或Haskell。如果Nebulas团队能够实现这一承诺并且非常失望,这将是一个非常重要的特征。

智能合约

让我们深入探讨在以太坊(Solidity)和Nebulas(JavaScript)中如何实现相同的结构。

转账

以太坊和Nebulas都具有最小的名义值,称为wei。1个ETH或1个NAS是10^18Wei。传递函数接受的值应为Wei的数量。在以太坊的情况下,它是uint256,对于Nebulas,它应该是BigNumber的一个实例。

1
address(address).transfer(value);
1
Blockchain.transfer(address, value);

交易属性

交易属性存在于全局命名空间中,并提供有关链的高度,块时间戳,供应的气体等的一组信息。

1
2
3
msg.sender          // sender address (address)
msg.value // number of Wei sent (uint256)
block.timestamp // current block timestamp (uint256)
1
2
3
Blockchain.transaction.from    // sender address (string)
Blockchain.transaction.value // number of Wei sent (string)
Blockchain.block.timestamp // current block timestamp (number)

使用混合大小写校验和编码可以进行以太坊地址验证,如EIP55所述,Vitalik Buterin的提议。钱包软件已广泛采用这种改进。由于使用了20字节的地址类型,因此无法使用此方法在链上验证它。Nebulas的地址有点不同;你可以从公钥计算校验和。它还包含有关地址是常规帐户还是智能合约的信息。

1
Blockchain.verifyAddress(address);

防止溢出

JavaScript中的最大安全整数是2 ^ 53 - 1. Solidity中的最大安全整数(无符号)甚至更大:2 ^ 256 - 1.在某些特定用例中,可能会溢出(或下溢)这些值。 要降低可能源自溢出的任何问题的严重性,你可以使用第三方库。

1
2
uint max = 2**256 - 1; // 115792089237316195423570985008687907853269984665640564039457584007913129639935
max + 1; // 0

在Solidity中,你可以使用流行的SafeMath库,它会抛出错误,消耗掉下溢或溢出时留下的所有气体。

1
2
3
4
5
6
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

using SafeMath for uint256;

uint max = 2**256 - 1;
max.add(1); // VM error

我们在Nebulas上运行的JavaScript驱动的智能合约可以使用bignumber.js而无需任何额外的导入。

1
2
3
4
5
6
7
8
const BigNumber = require("bignumber.js");

Number.MAX_SAFE_INTEGER; // 9007199254740991
Number.MAX_SAFE_INTEGER + 1; // 9007199254740992
Number.MAX_SAFE_INTEGER + 2; // 9007199254740992

const number = new BigNumber(Number.MAX_SAFE_INTEGER);
number.plus(2).toString(); // "9007199254740993"

合约结构

Solidity是一种面向联系的语言。这意味着它是一种面向对象的语言,带有一个contract关键字,用于定义类似类的类型,能够通过函数存储状态并为此状态提供行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
contract Crowdsale is MintedCrowdsale, CappedCrowdsale {
constructor(uint256 _rate, address _wallet, ERC20 _token) public {
// ...
}

function () public payable {
buyTokens(msg.sender);
}

function buyTokens(address _beneficiary) public payable {
// ...
}
}

此外,Solidity还支持接口和类似Python的多重继承(通过C3超类线性化)。

在Nebulas上,合约是一个类(或函数),其原型上有可用的方法。在合约初始化期间需要并执行一个函数init;它接受合约创建期间传递的参数。

1
2
3
4
5
6
7
class StandardToken {
init() {
// ...
}
}

module.exports = StandardToken;

状态变量

如果不将事件日志计为第四种,则Solidity有三种类型的存储:存储,内存和堆栈。存储保持合约状态变量。

1
2
3
4
5
6
7
contract Ownable {
address owner;

constructor() public {
owner = msg.owner;
}
}

Nebulas在其存储功能之上提供抽象。使用LocalContractStorage,我们必须指出哪些变量应该显式保留。

1
2
3
4
5
6
7
8
9
class Ownable {
constructor() {
LocalContractStorage.defineProperty(this, "storage");
}

init() {
this.owner = Blockchain.transaction.from;
}
}

Visibility

Solidity有四个可见性说明符:public,private,external和internal。公共说明符允许外部和内部调用,而私有函数只能从定义它们的合约中调用。内部函数像私有函数一样工作,但扩展合约也可以调用它们。外部函数可由其他合约和交易调用,也可在内部使用this关键字调用。

1
2
3
4
5
6
7
8
9
contract Visibility {
function visible() pure public {}

function hiddenFromOthers() pure private {}

function visibleOnlyForFunctions() pure external {}

function visibleForChildContracts() pure internal {}
}

在Nebulas上,私有函数是通过命名约定实现的,而不是由语言强制实现的。所有以下划线开头的函数都不是接口的一部分,不能通过交易调用。

1
2
3
4
5
6
7
class Visibility {
function visible() {
this._hidden();
}

function _hidden() {}
}

客户端应用程序

以太坊dApp使用注入的web3实例与嵌入式提供程序,每次dApp尝试签署交易时都会要求用户进行确认。MetaMask是你的浏览器的以太坊扩展,支持此流程,以及Mist和Status(带有适用于桌面和移动设备的dApps浏览器的钱包应用程序)。

使用Nebulas dApps时,你可以安装WebExtensionWallet。它缺乏方便的web3抽象,但它对于PoC和简单的用例来说已经足够了。发送交易的API与直接使用RPC非常相似。实际上,直接使用RPC是进行不需要签名的调用的最简单方法。

部署

在以太坊中部署合约有多种方法。最适合开发人员的是Remix和Truffle迁移脚本。Nebulas在其网络钱包中提供类似Mist的体验。你复制并粘贴合约源代码,指定构造函数参数,然后你就可以了。

或者,你可以将合约源更改为转义字符串并发送交易,该交易使用RPC创建新合约。

测试

由于其不可变性和代价高昂的错误,测试是智能合约开发中最重要的部分之一。Nebulas生态系统处于起步阶段,没有任何工具可以进行此类测试。虽然笨拙,但测试Nebulas智能合约并非不可能。 它需要模拟内部API,但是,一旦你下定决心,你将或多或少地可靠地测试合约。

在Solidity中测试智能合约要容易得多。由于Truffle团队的努力,你几乎可以在Solidity和JavaScript中单独可靠地测试合约。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
pragma solidity 0.4.24;

import "truffle/Assert.sol";
import "../contracts/Ownable.sol";


contract OwnableTest {
Ownable ownable;

function beforeEach() public {
ownable = new Ownable();
}

function testConstructor() public {
Assert.equal(ownable.owner(), address(this), "owner address is invalid");
}

// ...
}

结论

坦率地说,自2017年中期以来,我认为Lisk将成为JavaScript智能合约的第一个平台。Nebulas让我感到惊讶。

当然,Nebulas无法与更成熟的以太坊生态系统相匹敌,但是提出更好的比较并不是这里的目标。我认为新项目应该更加温和一点,并且要提前做好自己的缺点。我最初的失望只是因为当时的巨额索赔。

当我退后一步时,很明显,Nebulas团队在过去几个月里取得了相当大的进步。我相信这是一个值得观察的项目,我希望释放主网不是为时过早,并且不会因为其他类似的项目而放慢开发速度。

======================================================================

分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是Nebulas一个新的JavaScript开发智能合约平台