4.1.1 語法介紹 block/msg/now
- block 在調(diào)用某個方法的時候,solidity 會提供一個block 的變量,把當(dāng)前塊的信息返回。
block.blockhash(uint blockNumber) returns (bytes32) 給定塊的哈希 - 僅適用于256個不包括當(dāng)前最新塊
block.coinbase (address) 當(dāng)前塊礦工地址
block.difficulty (uint) 當(dāng)前塊難度
block.gaslimit (uint) 當(dāng)前塊gaslimit
block.number (uint) 當(dāng)前數(shù)據(jù)塊號
block.timestamp (uint) 當(dāng)前塊時間戳從unix紀(jì)元開始為秒
- msg 在調(diào)用某個方法的時候,會給方法傳遞一個msg的屬性,用來傳遞消息
msg.data (bytes) 完整的 calldata
msg.gas (uint) 剩余gas
msg.sender (address) 該消息(當(dāng)前呼叫)的發(fā)送者
msg.sig (bytes4) 呼叫數(shù)據(jù)的前四個字節(jié)(即功能標(biāo)識符)
msg.value (uint) 發(fā)送的消息的數(shù)量
- now (uint) 當(dāng)前塊時間戳(block.timestamp的別名)
4.1.2 存儲 storage / memory
Storage 變量是指永久存儲在區(qū)塊鏈中的變量。 Memory 變量則是臨時的,當(dāng)外部函數(shù)對某合約調(diào)用完成時,
內(nèi)存型變量即被移除。 你可以把它想象成存儲在你電腦的硬盤或是RAM中數(shù)據(jù)的關(guān)系。大多數(shù)時候你都用不到這
些關(guān)鍵字,默認(rèn)情況下 Solidity 會自動處理它。 狀態(tài)變量(在函數(shù)之外聲明的變量)默認(rèn)為“存儲”形式,
并永久寫入?yún)^(qū)塊鏈;而在函數(shù)內(nèi)部聲明的變量是“內(nèi)存”型的,它們函數(shù)調(diào)用結(jié)束后消失。
4.1.3 隨機(jī)數(shù)
生成一個0-100 之間的隨機(jī)數(shù)
function randomUtils() public view returns(uint) {
//定義數(shù)字。
uint random=1;
//基于數(shù)字的基礎(chǔ)上生成隨機(jī)數(shù).
//keccak256 生成數(shù).
return uint(keccak256(now,msg.sender,random)) % 100;
}
4.1.4 require 關(guān)鍵字
require(keccak256(_name) == keccak256("Vitalik"));
require使得函數(shù)在執(zhí)行過程中,當(dāng)不滿足某些條件時拋出錯誤,并停止執(zhí)行:
用來比較兩個字符串是否相等.
function equals(string str, string str1) public pure returns (bool) {
return (keccak256(str) == keccak256(str1));
}
4.1.5 modify
pragma solidity^0.4.19;
contract ModifyContract {
address owner;
//定義占位符,可以把需要判斷的條件共性的地方進(jìn)行抽取。
modifier onlyOwner() {
require(owner == msg.sender);
_;
}
//在調(diào)用方法之前會先進(jìn)行檢查.
function getRightToVote() public onlyOwner {
}
}
4.2發(fā)布合約
使用 Remix IDE,寫入代碼后,選擇 solc 版本,再進(jìn)行編譯。然后到 Run Tab頁,選擇好 環(huán)境,賬戶 等信息,設(shè)置 Gas Limit (一般 Remix 會自動設(shè)置一個值),點擊 Create 發(fā)布合約。發(fā)布合約需要花費(fèi) Gas。
合約發(fā)布之后,用戶可以點擊合約函數(shù),執(zhí)行函數(shù)。有一些函數(shù)需要 Gas,而有一些函數(shù)則不需要 Gas。
4.5調(diào)試
進(jìn)入 Debugger Tab 頁,可以進(jìn)行調(diào)試。
5 solidity 急行軍
案例1 轉(zhuǎn)賬給智能合約賬戶
當(dāng)一個智能合約運(yùn)行時,它運(yùn)行在以太坊上,任何人都可以調(diào)用函數(shù),向智能合約轉(zhuǎn)錢
pragma solidity^0.4.24;
contract Money {
function Money(){
}
//向智能合約賬戶轉(zhuǎn)錢
function paymoney () payable public{
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
案例2 從智能合約賬戶取錢
這個例子,展示如何從智能合約賬戶取錢,在這個例子里,取錢沒有任何條件,
只要合約賬戶中有錢,就可以取出這部分錢來
pragma solidity^0.4.19;
contract GetMoney {
//合約發(fā)布者
address owner;
//發(fā)布合約的時候會調(diào)用構(gòu)造函數(shù).
function GetMoney() public {
owner = msg.sender;
}
//向合約賬戶轉(zhuǎn)錢。
function payMoney() payable public {
}
//查看智能合約賬戶的余額
function getBalance() public view returns(uint) {
return address(this).balance;
}
//誰調(diào)用就往誰的賬戶打錢。從智能轉(zhuǎn)化里面轉(zhuǎn)錢.
function getMoney() public {
address who = msg.sender;
if(getBalance() > 2 ether) {
who.transfer(2 ether);
}
}
//銷毀合約.
function kill() public {
//判斷操作,如果合約的發(fā)布者是調(diào)用著,則有權(quán)限銷毀合約.
if(owner == msg.sender) {
selfdestruct(msg.sender);
}
}
}
案例3 土豪發(fā)紅包
```JavaScript
pragma solidity^0.4.19;
contract RedPacket {
//設(shè)置土豪.
address tuhao;
//初始化紅包的個數(shù).
int number;
//初始化相關(guān)數(shù)據(jù).
function RedPacket(int _number) public payable{
tuhao = msg.sender;
number = _number;
}
//獲取合約的余額.
function getBalance() public view returns(uint){
return address(this).balance;
}
//搶紅包
function stakeMoney() public payable returns(bool) {
address who = msg.sender;
if(number > 0) {
number --;
uint random = uint(keccak256(now,msg.sender,10)) % 100;
uint balance = getBalance();
who.transfer(balance * random / 100);
return true;
}
return false;
}
//destory contract
function kill() public {
if(tuhao == msg.sender) {
selfdestruct(tuhao);
}
}
}
```
案例4 博彩賭大小.
pragma solidity^0.4.19;
contract Bet {
address owner; //contract manager
struct Player {
address addr;
uint money;
}
Player [] inbig;
Player [] insmall;
uint blockNumber;
uint totalBig;
uint totalSmall;
function Bet() public {
owner = msg.sender;
blockNumber = block.number;
totalBig = 0;
totalSmall = 0;
}
function getBalance() public view returns(uint) {
return address(this).balance;
}
function getBlockNumber() public view returns(uint,uint){
return (blockNumber,block.number);
}
//押注 大小.
function stake(bool flag) public view returns (bool){
//先結(jié)構(gòu)化玩家.
Player memory player = Player(msg.sender,msg.value);
//玩家是否帶錢過來.
if(player.money > 0){
return false;
}
//押注大的
if(flag){
inbig.push(player);
totalBig +=player.money;
}else{ //押注小的.
insmall.push(player);
totalSmall +=player.money;
}
return true;
}
//開獎。
function open() payable public returns (bool) {
//設(shè)置開獎限制,必須最少得有兩個人押注.
if(block.number < 2+blockNumber) {
return false;
}
//押注大大金額以及押注小大金額大比例。
if(totalSmall == 0 && totalBig == 0){
return false;
}
//計算開大開小的規(guī)則,根據(jù)當(dāng)前塊的hash 值去定.
uint hash = uint(block.blockhash(block.number));
uint points = hash % 18;
uint i=0;
uint count;
Player memory player;
if(points>9) { // big winer
count=inbig.length;
for(i=0;i<count;i++){
player = inbig[I];
player.addr.transfer(player.money+totalSmall*player.money/totalBig);
}
}else { // small winer
count = insmall.length;
for(i=0;i<count;i++){
player = insmall[I];
player.addr.transfer(player.money+totalBig*player.money/totalSmall);
}
}
return true;
}
//銷毀合約
function kill() public {
if(msg.sender == owner){
selfdestruct(owner);
}
}
}
案例5 社區(qū)投票
需求:
投票,委托代理人投票,給某個voter 賦予投票的權(quán)利
獲取到最高的選題Prososal的name
//合約名
contract Ballot {
// 投票者結(jié)構(gòu)體
struct Voter {
uint weight; // 份額(既擁有多少票)
bool voted; // 是否已經(jīng)投票
address delegate; // 委任誰進(jìn)行投票
uint vote; // 第幾個投票議案
}
// 議案機(jī)構(gòu)體
struct Proposal {
bytes32 name; // 議案名(最多32字節(jié))
uint voteCount; // 累計投票數(shù)
}
address public chairperson; //投票主持人
// 投票者與其地址的映射
mapping(address => Voter) public voters;
// 提案指針
Proposal[] public proposals;
/// Ballot函數(shù),創(chuàng)建新投票,輸入多個議案名
function Ballot(bytes32[] proposalNames) public {
chairperson = msg.sender;
voters[chairperson].weight = 1;
for (uint i = 0; i < proposalNames.length; i++) {
// `Proposal({...})` 創(chuàng)建一個臨時Proposal對象
proposals.push(Proposal({
name: proposalNames[I],
voteCount: 0
}));
}
}
//輸入投票者地址,給予投票者投票權(quán)限
function giveRightToVote(address voter) public {
// require防止函數(shù)被錯誤調(diào)用,判斷為錯誤時終止調(diào)用
// 并恢復(fù)到調(diào)用前的狀態(tài),但是注意會消耗gas
require(
(msg.sender == chairperson) &&
!voters[voter].voted &&
(voters[voter].weight == 0)
);
voters[voter].weight = 1;
}
/// 輸入他人地址,委任他人投票
function delegate(address to) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted);
// 不允許委任自己
require(to != msg.sender);
// 循環(huán)委任直至被委任人不再委任他人,
// 但注意這種循環(huán)是危險的,有可能耗盡gas來進(jìn)行計算。
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
// 避免循環(huán)委任,形成委任環(huán)鏈
require(to != msg.sender);
}
// 此處sender為voters[msg.sender]
sender.voted = true;
sender.delegate = to;
Voter storage delegate_ = voters[to];
if (delegate_.voted) {
// 如果被委任人已經(jīng)投票,直接增加該議案票數(shù)
proposals[delegate_.vote].voteCount += sender.weight;
} else {
// 如果被委任人未投票,增加被委任人持有票數(shù)
delegate_.weight += sender.weight;
}
}
/// 向議案投票
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted);
sender.voted = true;
sender.vote = proposal;
// 提案超出數(shù)組范圍時自動中斷并恢復(fù)所以修改
proposals[proposal].voteCount += sender.weight;
}
/// 返回獲得票數(shù)最高的議案索引
function winningProposal() public view
returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}
// 返回獲得票數(shù)最高的議案名
function winnerName() public view
returns (bytes32 winnerName_)
{
winnerName_ = proposals[winningProposal()].name;
}
}
案例6 競拍 (代碼)
contract SimpleAuction {
address public beneficiary;
//競拍開始
uint public auctionStart;
uint public biddingTime;
//當(dāng)前的拍賣狀態(tài)
address public highestBidder;
uint public highestBid;
//在結(jié)束時設(shè)置為true來拒絕任何改變
bool ended;
//當(dāng)改變時將會觸發(fā)的Event
event HighestBidIncreased(address bidder, uint amount);
event AuctionEnded(address winner, uint amount);
//下面是一個叫做natspec的特殊注釋,
//由3個連續(xù)的斜杠標(biāo)記,當(dāng)詢問用戶確認(rèn)交易事務(wù)時將顯示。
///創(chuàng)建一個簡單的合約使用`_biddingTime`表示的競拍時間,
/// 地址`_beneficiary`.代表實際的拍賣者
function SimpleAuction(uint _biddingTime,
address _beneficiary) {
beneficiary = _beneficiary;
auctionStart = now;
biddingTime = _biddingTime;
}
///對拍賣的競拍保證金會隨著交易事務(wù)一起發(fā)送,
///只有在競拍失敗的時候才會退回
function bid() {
//不需要任何參數(shù),所有的信息已經(jīng)是交易事務(wù)的一部分
if (now > auctionStart + biddingTime)
//當(dāng)競拍結(jié)束時撤銷此調(diào)用
throw;
if (msg.value <= highestBid)
//如果出價不是最高的,發(fā)回競拍保證金。
throw;
if (highestBidder != 0)
highestBidder.send(highestBid);
highestBidder = msg.sender;
highestBid = msg.value;
HighestBidIncreased(msg.sender, msg.value);
}
///拍賣結(jié)束后發(fā)送最高的競價到拍賣人
function auctionEnd() {
if (now >= auctionStart + biddingTime)
throw;
//拍賣還沒有結(jié)束
if (ended)
throw;
//這個收款函數(shù)已經(jīng)被調(diào)用了
AuctionEnded(highestBidder, highestBid);
//發(fā)送合約擁有所有的錢,因為有一些保證金可能退回失敗了。
beneficiary.send(this.balance);
ended = true;
}
function () {
//這個函數(shù)將會在發(fā)送到合約的交易事務(wù)包含無效數(shù)據(jù)
//或無數(shù)據(jù)的時執(zhí)行,這里撤銷所有的發(fā)送,
//所以沒有人會在使用合約時因為意外而丟錢。
throw;
}
}
博彩游戲
需求部分:
玩法規(guī)則
【缺圖】
合約需求
- 押注
- 開獎
- 計算賠率
- 領(lǐng)取獎勵
合約代碼實例
pragma solidity ^0.4.19;
contract LotteryBase {
address public manager; // 彩票管理員
string public name; // 彩票名稱
uint public baseBlock; // 當(dāng)前售賣到的彩票期數(shù) 基準(zhǔn)區(qū)塊,也是彩票的期數(shù) 10
uint public stopBlock; // 彩票從當(dāng)前塊數(shù)+到特定塊數(shù)這一期間為售賣期間 關(guān)閉彩票售賣通道區(qū)塊 100
uint public openBlock; // 到了特定期間后再+到特定期間為開獎期間 開獎區(qū)塊 110
//開獎期數(shù)號碼記錄,用于彩民備查
struct OpenCode {
uint block; // 等于 baseBlock
uint8[] opencode; // 開獎號碼
}
// 所有開獎號碼集合
OpenCode[] public allOpenCodes;
// 獎金賬本,記錄每一個用戶的獎金
mapping(address=>uint) public bonus; // 獎金
// 所有中獎用戶的獎金綜合
uint public totalBonus; // 總獎金金額,獎池金額 = 余額 - 獎金總金額
function LotteryBase () public {
manager = msg.sender;
}
modifier onlyManager () {
require (manager == msg.sender);
_;
}
// 兩個抽象接口
// function chipin(uint8[] number, uint8 multi) public payable;
//function open() public;
// 未分配獎池的獎金金額
function getBonusPool() public view returns (uint) {
return address(this).balance - totalBonus;
}
}
contract KuaiSan is LotteryBase {
//不同下注不同賠率列表
uint8[19] public odds=[0,0,0,240,80,40,25,16,12,10,9,9,10,12,16,25,40,80,240];
//定義下注方式的枚舉類型
enum InjectionType {TypeSum, TypeSameThree,TypeSameThreeSingle,TypeSameTwo,TypeSameTwoSingle,TypeNoSameThree,TypeNoSameTwo,TypeThreeConsecutive }
//購買彩票的結(jié)構(gòu)體
struct Order {
address player;
uint8[] number; // 彩票號碼
uint8 multi;
InjectionType injectionType;//投注類型
uint8 sumVal;//如果是和值類型,那么該值為下注的和值
}
// 訂單集合
Order[] orders;
// 彩票價格,大約2人民幣
uint constant fee = 0.001 ether;
uint constant stopInterval = 30; //設(shè)置停止間隔
uint constant openInterval = 40; //設(shè)置開獎間隔
uint constant codeAOffset = 33; //這只當(dāng)前區(qū)塊+33的hash值給A數(shù)
uint constant codeBOffset = 34;//這只當(dāng)前區(qū)塊+33的hash值給B數(shù)
uint constant codeCOffset = 35;//這只當(dāng)前區(qū)塊+33的hash值給C數(shù)
function KuaiSan() public { //構(gòu)造函數(shù),開始競猜
// 開獎將基于 baseBlock + 33, baseBlock + 34, baseBlock + 35
baseBlock = block.number; //將當(dāng)前區(qū)塊設(shè)置到baseBlock中
stopBlock = baseBlock + stopInterval; //設(shè)置停止區(qū)塊為當(dāng)前區(qū)塊+開獎間隔 about 450 seconds
openBlock = baseBlock + openInterval; //設(shè)置開獎區(qū)塊為當(dāng)前區(qū)塊+開獎區(qū)塊 about 150 seconds
name = "中國福利彩票北京快三";
}
// 下注,玩家提供一個號碼和倍數(shù),記錄到訂單中
// number是玩家購買的號碼,multi是玩家要購買的倍數(shù),injType為玩家下注方式,_sumVal是和值類型的和值數(shù)
function chipin(uint8[] number, uint8 multi, InjectionType injType, uint8 _sumVal) public payable {
require(msg.value >= fee * multi); //檢查下玩家投注的金額和倍數(shù)是不是一樣
require(block.number <= stopBlock); //檢查當(dāng)前塊數(shù)是可以下注的塊數(shù)
if(injType == InjectionType.TypeSum ){ //判斷玩家下注方式是不是和值類型
require(_sumVal >= 3 && _sumVal <= 18); //檢查和值數(shù)不能小于3并且不能大于18
}
Order memory order = Order(msg.sender, number, multi, injType, _sumVal); //新建一個Order結(jié)構(gòu)體
orders.push(order);//將Order結(jié)構(gòu)體存儲起來
}
//計算獎金函數(shù)-通過下注code信息計算獎金情況,返回獎金值
//number是玩家購買的號碼,sumVal是值數(shù),multi是玩家要購買的倍數(shù),injType為玩家下注方式,openCode是開獎號碼
function calcBonus(uint8[] number,uint8 sumval, uint8 multi, InjectionType injectionType,uint8[] opencode) public view returns (uint){
//對于和值類型投注,下注金額不能小于1大于18
//如果是和值類型,計算和值是否相等
if(injectionType == InjectionType.TypeSum){ //如果玩家選擇的是和值類型
uint injVal = opencode[0]+opencode[1]+opencode[2]; //開獎號碼總和
if(sumval == injVal){ //如何玩家的sumval和開獎號碼和值相等的話
return fee * odds[injVal] * multi / 2; //返回該獲得的獎金
}
return 0;
}
//三同號通選 要求三個號碼相同即可
if(injectionType == InjectionType.TypeSameThree){
if(opencode[0] == opencode[2]){
return fee * 40 * multi / 2;
}
return 0;
}
//三同號單選
if(injectionType == InjectionType.TypeSameThreeSingle){
if(opencode[0] == opencode[2] && number[0] == opencode[0]){
return fee * 240 * multi / 2;
}
return 0;
}
//二同號復(fù)選 只要任意兩個號碼相同即可
if(injectionType == InjectionType.TypeSameTwo){
if((opencode[0] == opencode[1] || opencode[1] == opencode[2]) && opencode[1] == number[0] ){
return fee * 15 * multi / 2;
}
return 0;
}
//二同號單選 要求指定的對子和單都相同
if(injectionType == InjectionType.TypeSameTwoSingle) {
if(opencode[0] == opencode[1] || opencode[1] == opencode[2]) {
if(opencode[0] == number[0] && opencode[1] == number[1] && opencode[2] == number[2]) {
return fee * 80 * multi / 2;
}
}
return 0;
}
//三不同號 要求開獎號碼是三個不同的
if(injectionType == InjectionType.TypeNoSameThree){
if(opencode[0] == number[0] && opencode[1] == number[1] && opencode[2] == number[2]) {
return fee * 40 * multi / 2;
}
return 0;
}
//二不同號 指定2個不同號碼和一個任意號碼
if(injectionType == InjectionType.TypeNoSameTwo){
if( (opencode[0] == number[0] && opencode[1] == number[1]) ||
(opencode[1] == number[0] && opencode[2] == number[1]) ) {
return fee * 8 * multi / 2;
}
return 0;
}
//三連號 可能情況 123 234 345 456
if(injectionType == InjectionType.TypeThreeConsecutive){
if(opencode[1]-opencode[0] == 1 && opencode[2]-opencode[1] == 1){
return fee * 10 * multi / 2;
}
return 0;
}
return 0;
}
//開盤函數(shù)
function open() public {
require(block.number > openBlock);//檢查一下當(dāng)前塊數(shù)大于設(shè)置的可開盤塊數(shù)
uint8[] memory openCode; //openCode是存儲開獎號碼
uint8 a = uint8(uint(block.blockhash(baseBlock + codeAOffset)) % 6 + 1); //將當(dāng)前區(qū)塊的hash值+codeAOffset,運(yùn)算出一個hash值與6取模并且+1
uint8 b = uint8(uint(block.blockhash(baseBlock + codeBOffset)) % 6 + 1); //將當(dāng)前區(qū)塊的hash值+codeBOffset,運(yùn)算出一個hash值與6取模并且+1
uint8 c = uint8(uint(block.blockhash(baseBlock + codeCOffset)) % 6 + 1); //將當(dāng)前區(qū)塊的hash值+codeCOffset,運(yùn)算出一個hash值與6取模并且+1
uint8 t;
//將開獎號碼排序
if (a > b) {
t = a;
a = b;
b = t;
}
if (b > c)
{
t = c;
c = b;
b = t;
}
if (a > b) {
t = a;
a = b;
b = t;
}
OpenCode memory code = OpenCode(baseBlock, openCode); //新建一個代碼號碼記錄
code.opencode[0] = a; //將記錄中的號碼賦值
code.opencode[1] = b;
code.opencode[2] = c;
// 記錄中獎號碼
allOpenCodes.push(code);
//計算獎金
uint i = 0;
uint bonusMoney; //記錄該獲得的獎金
for(i=0; i<orders.length; ++i) { //循環(huán)遍歷每一個競猜用戶
Order memory o = orders[i]; //o是遍歷的orders寄存器
//uint8[] number,uint8 sumval, uint8 multi, InjectionType injectionType,uint8[] opencode
bonusMoney = calcBonus(o.number, o.sumVal, o.multi, o.injectionType, code.opencode); //調(diào)用calcBonus函數(shù)取得應(yīng)該獲得的獎金給bonusMoney
if (bonusMoney > 0){
bonus[o.player] += bonusMoney; //獎金映射,將獲得獎金映射到地址中
totalBonus += bonusMoney; //增加總獎金金額
}
}
uint bonusMoney = fee * 120;
uint i = 0;
for(i=0; i<orders.length; ++i) {
Order memory o = orders[I];
if(o.number[0] == code.opencode[0]
&& o.number[1] == code.opencode[1]
&& o.number[2] == code.opencode[2]) {
bonus[o.player] += bonusMoney * o.multi;
totalBonus += bonusMoney * o.multi;
}
}
// 重置數(shù)據(jù),開始下一輪競猜
delete orders;
baseBlock = block.number;
stopBlock = baseBlock + 30; // about 450 seconds
openBlock = stopBlock + 10; // about 150 seconds
}
// 彩民獲取獎金
function withdraw() public {
uint money = bonus[msg.sender]; //獎金寄存器
require(money > 0); //檢查money大于0
delete bonus[msg.sender]; //清楚該地址映射
totalBonus -= money; //總獎金金額減少
msg.sender.transfer(money); //給該地址返還獎金
}
}
中心服務(wù)器部分
node.js 服務(wù)器 安裝初始化
npm init
安裝web3.js到項目中:
npm install web3 --save
在服務(wù)器使用web3.js
在web3test目錄下新建index.js文件,在其中輸入以下代碼:
var Web3 = require("web3");
var web3 = new Web3();
var web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"));
獲取已部署的智能合約實例
var abi = /*編譯器生成的abi代碼*/;
var contractAddress = '/*這里是合約的地址*/';
var hello = new web3.eth.Contract(abi,address);
調(diào)用節(jié)點
- 查看節(jié)點所有賬戶
var faq = web3.eth.getAccounts(function(error,result){
if(!error)
resp.send(result);
});
console.log(faq);
- 創(chuàng)建用戶
var daq=web3.eth.personal.newAccount("1234",function(error,result){
if(!error)
resp.send(result);
});
- 解鎖
var faq=web3.eth.personal.unlockAccount("0xc40b465e28a386c56806058571d0baf303af079c","123",function(error,result){
if(!error)
resp.send(result);
});
console.log(faq);
- 調(diào)用合約
函數(shù)下面是調(diào)用一個只讀函數(shù),后面參數(shù)call是表明此調(diào)用不會產(chǎn)生數(shù)據(jù)更改,只會在一個節(jié)點上處理數(shù)據(jù),也不會消耗gas,function是回調(diào)函數(shù),回調(diào)函數(shù)的返回值就是函數(shù)的返回值。
下面是調(diào)用一個只讀函數(shù),后面參數(shù)call是表明此調(diào)用不會產(chǎn)生數(shù)據(jù)更改,只會在一個節(jié)點上處理數(shù)據(jù),也不會消耗gas,function是回調(diào)函數(shù),回調(diào)函數(shù)的返回值就是函數(shù)的返回值。
hello.methods.helloworld().call(function(error,result){
if(!error)
resp.send(result);
});
下面的是一個調(diào)用接受轉(zhuǎn)賬的函數(shù),from是轉(zhuǎn)賬的賬戶,value是轉(zhuǎn)賬的數(shù)額,單位是wei,gas就是設(shè)定的gas,function是后面接的回調(diào)函數(shù),回調(diào)函數(shù)的返回值是交易地址,還沒有找到如何去查看函數(shù)的返回值。
hello.methods.hellomoney().send({from:"0xc40b465e28a386c56806058571d0baf303af079c",value: 200000000,gas:3000000},function(error,result){
if(!error)
resp.send(result);
});
hello.methods.helloPDJ().send({from:"0xc40b465e28a386c56806058571d0baf303af079c",gas:3000000},function(error,result){
if(!error)
resp.send(result);
})
上面調(diào)用會變更數(shù)據(jù),但不接受轉(zhuǎn)賬的函數(shù),from是發(fā)送調(diào)用的地址,
function是回調(diào)函數(shù),回調(diào)函數(shù)的返回值是交易地址,還沒有找到如何去查看函數(shù)的返回值。