Truffle - 以太坊Solidity编程语言开发框架

  1. 构建应用
    原文地址:http://truffleframework.com/docs/getting_started/build

默认构建
Truffle集成了默认的构建来方便使用。但也许不适合每个项目,所以你也许需要其它的来打包你的应用。在3. 构建流程里查看更多信息。默认的构造目标是web应用,但也可以很容易的转变为其它的构造流程,比如适用于命令行或库的流程。

特性
默认构建有一些特性来帮助你快速的开始:

在浏览器内自动的初始化你的应用,包括引入你编译的合约,部署的合约信息,和以太坊客户端信息配置。
包含常见的依赖,如web3和Ether Pudding
内置支持ES6和JSX
SASS支持
Uglifyjs支持
配置
你可以随间的修改默认的构建内容,原始的构建内容目录如下:

app/
- javascripts/
- app.js
- stylesheets/
- app.css
- images/
- index.html
在1. 配置文件中的构建配置文件如下:

{
“build”: {
// Copy ./app/index.html (right hand side) to ./build/index.html (left hand side).
“index.html”: “index.html”,

// Process all files in the array, concatenating them together
// to create a resultant app.js
"app.js": [
  "javascripts/app.js"
],

// Process all files in the array, concatenating them together
// to create a resultant app.css
"app.css": [
  "stylesheets/app.scss"
],

// Copy over the whole directory to the build destination.
"images/": "images/"

}
}
配置文件中的配置键描述了最终的打包目标名称,右边的配置目录或文件数组则是要打包的目录的内容。打包过程根据文件扩展,将文件连接形成一个结果文件,并放到构建的目标位置。如果指定的是一个字符串而不是一个数组,这个字符串代指的文件如果需要会直接拷到对应的构建目录。如果字符串以“/”结尾,则会被识别为一个目录,整个目录会不经调整直接拷贝到对应的目录。所以的指定值都是默认相对于/app目录来指定的。

你可以在任何时间改变配置和目录结构。并不强制要求需要javascript和css文件目录,所以删除构建配置文件中的对应配置就可以了。

特别注意:如果你想默认构建在前端初始化你的应用,务必保证有一个构造目标app.js,因为默认构建会将相关代码附加到这个文件,而不是其它文件。

命令
要创建你的前端工程,执行:

truffle build
构建结果
构建结果存在./build目录。所以合约文件则在对应的位置./build/contracts。

注意事项
默认构建虽简单易用,但它仍有一些缺点:

当前不支持import,require等。所以不能提供browserify,Webpack和CommonJS这样的工具。由此让依赖管理变得有些困难。

这是一套自定义的构建系统,与其它流行构建系统不兼容。

它可以扩展,但是自定义的方法和API。

默认构建在将来可能会被取代,但在较长时间里,都将会是默认的以支持之前构建的DAPP.Truffle提供了许多方式来切换到不同的构建流程,可以在3. 构建流程这里找到更多的例子。

如果任何问题,欢迎留言批评指正。
7. 合约交互
原文地址:http://truffleframework.com/docs/getting_started/contracts

背景
标准的与以太坊网络交互的方法是通过以太坊官方构建的Web3库。尽管这个库非常有用,但使用其提供接口与合约交互有些困难,特别是以太坊的新手。为降低学习曲线,Truffle使用Ether Pudding库,它也是基于Web3的基础之上,目的是为了让交互更简单。

读写数据
以太坊网络把在网络上读与写数据进行了区分,这个区分对于如何写程序影响很大。通常来说,写数据被称作交易(transaction),读数据被称作调用(call)。对于交易与调用,他们分别有如下特性:

交易(Transaction)
交易本质上改变了整个以太坊网络的数据状态。一个交易可以是向另一个帐户发送ether(以太坊网络代币)这样的简单行为,也可以是执行合约函数,添加一个新合约到以太坊网络这样的复杂行为。交易的典型特征是写入(或修改)数据。交易需要花费ether,也被称作gas,交易的执行需要时间。当你通过交易执行一个合约的函数时,你并不能立即得到执行结果,因为交易并不是立即执行的。大多娄情况下,通过执行交易不会返回值;它会返回一个交易的ID.总的来说,交易具有如下特征:

需要gas(Ether)
改变网络的状态
不会立即执行
不会暴露返回结果(仅有交易ID)
调用
调用,则与上述的交易非常不同。调用可以在网络上执行代码,但没有数据会被改变(也许仅仅是些临时变量被改变)。调用的执行是免费的,典型的行为就是读取数据。通过调用执行一个合约函数,你会立即得到结果。总的来说,调用具有如下特征:

免费(不花费gas)
不改变网络状态
立即执行
有返回结果。
如果选择,取决于你想干什么,或者说想写数据,还是读数据。

接口(abstract)
为了来体验一下合约接口的作用,我们使用框架自带的默认metacoin的合约例子。

import “ConvertLib.sol”;

contract MetaCoin {
mapping (address => uint) balances;

event Transfer(address indexed _from, address indexed _to, uint256 _value);

function MetaCoin() {
    balances[tx.origin] = 10000;
}

function sendCoin(address receiver, uint amount) returns(bool sufficient) {
    if (balances[msg.sender] < amount) return false;
    balances[msg.sender] -= amount;
    balances[receiver] += amount;
    Transfer(msg.sender, receiver, amount);
    return true;
}
function getBalanceInEth(address addr) returns(uint){
    return ConvertLib.convert(getBalance(addr),2);
}
function getBalance(address addr) returns(uint) {
    return balances[addr];
}

}
合约有三个方法和一个构造方法。所有三个方法可以被执行为交易或调用。

现在我们来看看Truffle和Ether Pudding为我们提供的叫MetaCoin的Javascript对象,可以在前端中使用:

// Print the deployed version of MetaCoin
console.log(MetaCoin.deployed());

// outputs:
//
// Contract
// - address: “0xa9f441a487754e6b27ba044a5a8eb2eec77f6b92”
// - allEvents: ()
// - getBalance: ()
// - getBalanceInEth: ()
// - sendCoin: ()
接口层提供了合约中以应的函数名。它还包含一个地址,指向到MetaCoin合约的部署版本。

执行合约函数
通过这套框架为我们提供的接口,我们可以简单的在以太坊网络上执行合约函数。

执行交易
在上述例子MetaCoin合约中,我们有三个可以执行的函数。如果你对这三个函数稍加分析就会发现,只有sendCoin会对网络造成更改。sendCoin函数的目标将Meta Coin从一个帐户发送到另一些帐户,这些更改需要被永久存下来。

当调用sendCoin,我们将把他们作为一个交易来执行。下面的例子我们来演示下把10个币,从一个帐户发到另一个帐户,改变要永久的保存在网络上:

var account_one = “0x1234…”; // an address
var account_two = “0xabcd…”; // another address

var meta = MetaCoin.deployed();
meta.sendCoin(account_two, 10, {from: account_one}).then(function(tx_id) {
// If this callback is called, the transaction was successfully processed.
// Note that Ether Pudding takes care of watching the network and triggering
// this callback.
alert(“Transaction successful!”)
}).catch(function(e) {
// There was an error! Handle it.
})
上述代码有一些有趣点,我们来了解一下:

我们直接调用接口的sendCoin函数。最终是默认以交易的方式来执行的。
交易被成功执行时,回调函数会直到交易被执行时才真正被触发。这样带来的一个好处是你不用一直去检查交易的状态。
我们对sendCoin函数传递了第三个参数,需要注意的是原始合约函数的定义中并没有第三个参数。这里你看到的是一个特殊的对象,用于编辑一些交易中的指定细节,它可以总是做为第三个参数传进。这里,我们设置from的地址为account_one.
执行调用
继续用MetaCoin的例子。其中的getBalance函数就是一个很好的从网络中读取数据的例子。它压根不需要进行任何数据上的变更,它只是返回传入的地址的帐户余额,我们来简单看一下:

var account_one = “0x1234…”; // an address

var meta = MetaCoin.deployed();
meta.getBalance.call(account_one, {from: account_one}).then(function(balance) {
// If this callback is called, the call was successfully executed.
// Note that this returns immediately without any waiting.
// Let’s print the return value.
console.log(balance.toNumber());
}).catch(function(e) {
// There was an error! Handle it.
})
一些有意思的地方如下:

我们必须通过.call()来显示的向以太坊网络表明,我们并不会持久化一些数据变化。
我们得到了返回结果,而不是一个交易ID。这里有个需要注意的是,以太坊网网络可以处理非常大的数字,我们被返回了一个BigNumber对象,框架再将这个对象转化了一个number类型。
警告:我们在上述的例子中将返回值转成了一个number类型,是因为例子中的返回值比较小,如果将一个BigNumber转换为比javascript支持的number最大整数都大,你将会出现错误或不可预期的行为。

捕捉事件(Catching Events)
你的合约可以触发事件,你可以进行捕捉以进行更多的控制。事件API与Web3一样。可以参考Web3 documentation来了解更多。

var meta = MetaCoin.deployed();
var transfers = meta.Transfer({fromBlock: “latest”});
transfers.watch(function(error, result) {
// This will catch all Transfer events, regardless of how they originated.
if (error == null) {
console.log(result.args);
}
}
METHOD:DEPLOYED()
每一个抽象出来的合约接口都有一个deployed()方法,上述例子中,你已经见到过。调用这个函数返回一个实例,这个实例代表的是之前部署到网络的合约所对应的抽象接口的实例。

var meta = MetaCoin.deployed();
警告:这仅对使用truffle deploy部署的合约,且一定是在project configuration中配置发布的才有效。如果不是这样,这个函数执行时会抛出异常。

METHOD:AT()
类似于deployed(),你可以通过一个地址来得到一个代表合约的抽象接口实例。当然这个地址一定是这个合约的部署地址。

var meta = MetaCoin.at(“0x1234…”)
警告:当你的地址不正确,或地址对应的合约不正确时,这个函数并不会抛出异常。但调用接口时会报错。请保证在使用at()时输入正确的地址。

METHOD:NEW()
你可以通过这个方法来部署一个完全全新的合约到网络中。

MetaCoin.new().then(function(instance) {
// instance is a new instance of the abstraction.
// If this callback is called, the deployment was successful.
console.log(instance.address);
}).catch(function(e) {
// There was an error! Handle it.
});
需要注意的是这是一个交易,会改变网络的状态。

如果任何问题,欢迎留言批评指正。
8. 测试合约
原文地址:http://truffleframework.com/docs/getting_started/testing

框架
Truffle使用Mocha测试框架来做自动化测试,使用Chai来做断言。这两个库的结合可能让人耳目一新,我们基于这两者之上,提供一种方式来编译简单和可管理的合约自动化测试用例。

位置
测试文件应置于./tests目录。Truffle只会运行以.js,.es,.es6和.jsx结尾的测试文件,其它的都会被忽略。

测试用例
每个测试文件至少应该包含至少一个对Mocha的describe()函数的调用,详情见Mochajs Documentation。另一种方式是使用Truffle自定义的contract()函数,作用类型describe()函数,但额外添加了一些特性:

在每一个contract()函数执行前,你的合约都会重部署到以太坊客户端中,这样测试用例会在一个干净状态下执行。
contract()函数支持传入多个可用的帐户做为第二个参数传入,你可以用此来进行测试。
当你需要与你写的合约进行交互时,使用contract(),否则使用describe()函数。

测试用例示例
truffle init命令为我们提供了一个简单的测试用例例子。它会先部署你的合约,然后执行在it()块中指定的测试用例。

contract(‘MetaCoin’, function(accounts) {
it(“should put 10000 MetaCoin in the first account”, function() {
// Get a reference to the deployed MetaCoin contract, as a JS object.
var meta = MetaCoin.deployed();

// Get the MetaCoin balance of the first account and assert that it's 10000.
return meta.getBalance.call(accounts[0]).then(function(balance) {
  assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account");
});

});
});
需要注意的是在contract()函数的传入的MetaCoin仅仅因为用来展示,说明它是MetaCoin相关的测试,并无本质作用。

合约
Truffle提供了接口抽象,方便你与合约进行便捷交互。通过var meta = MetaCoin.deployed()这行。Truffle设法保证了,你可以在测试用例,前端,移植(Migration)中都能用这种方式与你自己写的合约进行交互。可以在7. 合约交互章节了解更多。

命令
要执行测试,执行下面的命令:

truffle test
你也可以对单个文件执行测试:

truffle test ./path/to/test/file.js
注意事项
EthereumJS TestRPC在进行自动化测试时相比其它客户端会快非常多。而且,TestRPC包含了一些,Truffle可以用来加速测试的特性。作为一个能用流程,我们建议你在开发和测试环节使用TestRPC。当你筹备好要发布到现上时,才使用Geth或其它官方以太坊客户端来进行一次测试。

更多
Truffle提供了操作Mocha的配置文件的入口。参见1. 配置文件章节来了解更多。

如果任何问题,欢迎留言批评指正。
9. 控制台
原文:http://truffleframework.com/docs/getting_started/console

背景
有时在进行测试和debug时,或手动执行交易时与合约进行直接交互是需要的。Truffle提供了一种更加简单的方式,通过交互式控制台来与你的那些准备好的合约进行交互。

命令
启动控制台,使用:

truffle console
这会使用默认网络来调起一个控制台,会自动连接到一个运行中的以太坊客户端。你可以使用选项–network来修改这个特性,更多细节参见2. 网络与APP部署和4. Truffle命令指南。

当你加载了控制台,你会看到下面的输出:

$ truffle console
truffle(default)>
default的意思是说,你当前连接到的是默认网络。

特性
控制台支持Truffle命令行支持的命令,比如,你可以在控制台中执行migrate –reset,其效果与在命令行中执行truffle migrate –reset的效果一致。Truffle的控制台额外增加如下特性:

所有已经编译的合约都可用。就像在开发测试,前端代码中,或者移植代码中那样使用。
在每个命令后,你的合约会被重新加载。如使用migrate –reset命令后,你可以立即使用新分配的地址和二进制。
web3库也可以使用,且也连到你了的以太坊客户端。
所有命令返回的promise,会自动解析,直接打印出结果,你可以不用输入then(),简化了命令。如下:
truffle(default)> MyContract.deployed().getValue.call(); //
5
如果任何问题,欢迎留言批评指正。
10. 外部脚本
原文:http://truffleframework.com/docs/getting_started/scripts

背景
你也许会经常的执行外部脚本来与你的合约进行交互。Truffle提供了一个简单的方式来进行这个。首先,启动你的合约,连上你想要的网络,通过1. 配置文件

命令
要执行外部(external)脚本,执行下述命令:

$ truffle exec

你可能感兴趣的:(区块链)