youchain-you-contract

youchain.you.contract 可以让你更方便地在 youchain 中与智能合约进行交互。当你创建一个新的合约,只提供合约对应的 json interface,youchain.js 会自动通过 RPC 调用帮你转换为低级别的 ABI 接口。就像使用 Javascript 对象一样来处理智能合约。

new contract

描述:json interface 对象包含了一个合约方法和事件的定义。

参数值:

  • jsonInterface - Array:初始化合约的 json 接口
  • address - String:交易和请求所需地址
  • options - Object:
    • from - String:交易创建者的地址
    • gasPrice - String:交易的 gas 费
    • gas - Number:交易所需最大 gas 费用
    • data - String:合约的字节码形式

返回值:Object 包含方法和事件的合约示例

new youchain.you.Contract(jsonInterface, address, options)

示例:

const myContract = new youchain.you.Contract([...], '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', {
    from: '0x1234567890123456789012345678901234567891', // default from address
    gasPrice: '20000000000' // 单位默认为 lu, 20 glu 
});

Properties

options

描述:合约实例的可选属性

属性:

  • address - String 发布时的合约地址
  • jsonInterface - Array 合约的 jsoninterface 对象
  • data - String 合约的字节码
  • from - String 创建交易的地址
  • gasPrice - String 交易的 gas 费
  • gas - Number 单笔交易最大 gas 费 (gas limit)

示例:

myContract.options;
> { 
    from: '0x1234567890123456789012345678901234567891',
    gasPrice: '20000000000',
    address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
}
myContract.options.from = '0x1234567890123456789012345678901234567891'; 
myContract.options.gasPrice = '20000000000'; 
myContract.options.gas = 5000000;

options.address

属性:address - String | null 合约地址,默认值为 null

示例:

myContract.options.address;
> '0x1234567890123456789012345678901234567891'

myContract.options.address = '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae';"

options.jsonInterface

属性:jsonInterface - Array 合约的 json 接口

示例:

myContract.options.jsonInterface;
> [{
    "type":"function",
    "name":"foo",
    "inputs": [{
        "name":"a",
        "type":"uint256"
    }],
    "outputs": [{
        "name":"b",
        "type":"address"
    }]
},{
    "type":"event",
    "name":"Event",
    "inputs": [{
        "name":"a",
        "type":"uint256",
        "indexed":true
},{
    "name":"b",
    "type":"bytes32",
    "indexed":false}],
}]
myContract.options.jsonInterface = [...];

Methods

clone

返回值:Object 新合约的示例

示例:

const contract1 = new you.Contract(abi, address, {gasPrice: '12345678', from: fromAddress});
const contract2 = contract1.clone();
contract2.options.address = address2;

(contract1.options.address !== contract2.options.address);
> true

deploy

参数值:

  • options 发布合约的可选项
    • data - String:合约字节码
    • arguments - Array:发布时传入的参数

返回值:Object 交易对象

  • Array:传入方法的参数
  • Function - send
  • Function - estimateGas
  • Function - encodeABI

示例:

myContract.deploy({
    data: '0x12345...',
    arguments: [123, 'My String']
})
.send({
    from: '0x1234567890123456789012345678901234567891',
    gas: 1500000,
    gasPrice: '30000000000000'
}, (error, transactionHash) => { ... })
.on('error', (error) => { ... })
.on('transactionHash', (transactionHash) => { ... })
.on('receipt', (receipt) => {
    console.log(receipt.contractAddress) // contains the new contract address
})
.on('confirmation', (confirmationNumber, receipt) => { ... })
.then((newContractInstance) => {
    console.log(newContractInstance.options.address)
});
// 设置合约的数据
myContract.options.data = '0x12345...';
myContract.deploy({
    arguments: [123, 'My String']
})
.send({
    from: '0x1234567890123456789012345678901234567891',
    gas: 1500000,
    gasPrice: '30000000000000'
})
.then((newContractInstance) => {
    console.log(newContractInstance.options.address) // instance with the new contract address
});

myContract.deploy({
    data: '0x12345...',
    arguments: [123, 'My String']
})
.encodeABI();
> '0x12345...0000012345678765432'

// 预估 Gas
myContract.deploy({
    data: '0x12345...',
    arguments: [123, 'My String']
})
.estimateGas((err, gas) => {
    console.log(gas);
});

methods

描述:为方法创建交易

参数值:方法参数取决于智能合约函数。

返回值:

  • Array:方法传入的参数。
  • Function - call:在 EVM 执行合约函数,但不能改变合约状态。
  • Function - send:把交易发送给智能合约,并执行方法,可改变合约状态。
  • Function - estimateGas:每个方法执行所需要的 gas 费
  • Function - encodeABI:为方法编码 ABI

示例:

myContract.methods.myMethod(123).call({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'}, (error, result) => {
    ...
});
// or sending and using a promise
myContract.methods.myMethod(123).send({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.then((receipt) => {
// receipt can also be a new contract instance, when coming from a "contract.deploy({...}).send()"
});
// or sending and using the events
myContract.methods.myMethod(123).send({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.on('transactionHash', (hash) => {
    ...
})
.on('receipt', (receipt) => {
    ...
})
.on('confirmation', (confirmationNumber, receipt) => {
    ...
})
.on('error', console.error);

methods.myMethod.call

参数值:

  • options
    • from - String:调用交易的地址
    • gasPrice - String:调用交易的 gas 费
    • gas - Number:调用交易所需最大的 gas 费
  • callback:智能合约方法执行的返回,第一个参数时错误信息

返回值:Promise - 智能合约函数返回的结果,如果是多值返回,会返回属性和索引组成的对象

示例:

myContract.methods.myMethod(123).call({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'}, (error, result) => {
    console.log("to do")
});
myContract.methods.myMethod(123).call({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.then((result) => {
    console.log("to do")
});
// Solidity

contract MyContract {
    uint public endTime;
    constructor() public {
      endTime = now + 2 days;
    }
    function myFunction()
    returns(uint256 myNumber, string myString) {
        return (23456, "Hello!%");
    }
}
const MyContract = new youchain.you.Contract(abi, address);
MyContract.methods.myFunction().call()
.then(console.log);

> Result {
    myNumber: '23456',
    myString: 'Hello!%',
    0: '23456', 
    // these are here as fallbacks if the name is not know or given   
    1: 'Hello!%'
}

// getter 方法获取变量值
MyContract.methods.endTime().call()
.then(result => {
    var endTime = new Date(result * 1000);
    // 把时间戳转化为本地时间
    var endDate = endTime.toLocaleDateString().replace(/\//g, "-") + " " + endTime.toTimeString().substr(0, 8);
    console.log('endDate: ', endDate);
});

> 12-30-2019 11:59:39


// Solidity
contract MyContract {
    function myFunction() returns(string myString) {
        return "Hello!%";
    }
}
const MyContract = new youchain.you.Contract(abi, address);
MyContract.methods.myFunction().call()
.then(console.log);
> "Hello!%"

methods.myMethod.send

参数值:

  • options - Object 发送的设置
    • from - String:交易发出的地址
    • gasPrice - String:发生交易的 gas 费
    • gas - Number:发生交易的最大 gas 费
    • value - Number | String | BN | BigNumber:
  • callback - Function:交易哈希作为第二个返回,错误信息为第一个参数

返回值:

  • PromiEvent
    • transactionHash - String:交易哈希值
    • receipt- Object:交易票据
    • confirmation - Number:交易确认数量
    • error - Error:发送交易失败时会触发

示例:

myContract.methods.myMethod(123).send({
    from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'}, (error, transactionHash) => {
});
// using the promise
myContract.methods.myMethod(123).send({
    from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
})
.then((receipt) => {
    console.log("...");
});
// using the event emitter
myContract.methods.myMethod(123).send({
    from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
})
.on('transactionHash', (hash) => {
    ...
})
.on('confirmation', (confirmationNumber, receipt) => {
    ...
})
.on('receipt', (receipt) => {
    console.log(receipt);

> {
    "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",        "transactionIndex": 0,
    "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
    "blockNumber": 3,
    "contractAddress": "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
    "cumulativeGasUsed": 314159,
    "gasUsed": 30234,
    "events": {     
        "MyEvent": {
            returnValues: {
                myIndexedParam: 20,
                myOtherIndexedParam: '0x123456789...',
                myNonIndexParam: 'My String'
        },
        raw: {
            data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
            topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
        },
        event: 'MyEvent',
        signature: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
        logIndex: 0,
        transactionIndex: 0,
        transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
        blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
        blockNumber: 1234,
        address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
        },
        "MyOtherEvent": {                
            ...
        },
        "MyMultipleEvent":[{
            ...
        }] // If there are multiple of the same event, they will be in an array
    }
})
.on('error', console.error);

methods.myMethod.estimateGas

参数值:

  • options - Object 发送的设置
    • from - String:交易发出的地址
    • gas - Number:调用交易的最大 gas 费
    • value - Number | String | BN | BigNumber:
  • callback - Function:交易预估 gas 费作为第二个返回,错误信息为第一个参数

返回值:Promise:预估的 gas 费用

示例:

myContract.methods.myMethod(123).estimateGas({
    gas: 5000000
}, function(error, gasAmount){
    if(gasAmount == 5000000)
        console.log('Method ran out of gas');
});
myContract.methods.myMethod(123).estimateGas({
    from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
})
.then(function(gasAmount){
        ...
})
.catch(function(error){
    ...
});

methods.myMethod.encodeABI

参数值:无

返回值:String 编码后的 ABI 字节码

示例:

myContract.methods.myMethod(123).encodeABI();
> '0x58cf5f1000000000000000000000000000000000000000000000000000000000000007B'

Events

once

参数值:

  • event - String:合约中的事件名称
  • options - Object:发布合约的选项
    • filter - Object:根据索引参数过滤事件
    • topics - Array:可手动设置时间过滤器的主题

返回值:undefined

示例:

myContract.once('MyEvent', {
    filter: {myIndexedParam: [20,23], myOtherIndexedParam: '0x123456789...'}, 
    fromBlock: 0    
}, (error, event) => { 
    console.log(event); 
});

> {
    returnValues: {
        myIndexedParam: 20,
        myOtherIndexedParam: '0x123456789...',
        myNonIndexParam: 'My String'
    },
    raw: {
        data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
        topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
    },
    event: 'MyEvent',
    signature: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
    blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    blockNumber: 1234,
    address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
}

events

描述:订阅一个事件

参数值:

  • options - Object:发布合约的选项
    • filter - Object:根据索引参数过滤事件
    • topics - Array:可手动设置时间过滤器的主题
  • callback - Function:事件作为第二个参数,错误作为第一个参数

返回值:

  • EventEmitter:
    • data - Object:
    • changed - Object:
    • error - Object:

示例:

myContract.events.MyEvent({
    filter: {
        myIndexedParam: [20,23], 
        myOtherIndexedParam: '0x123456789...'},
        fromBlock: 0
    }, (error, event) => { 
        console.log(event); 
})
.on('data', (event) => {
    console.log(event); 
})
.on('changed', (event) => {
})
.on('error', console.error);

> {
    returnValues: {
        myIndexedParam: 20,
        myOtherIndexedParam: '0x123456789...',
        myNonIndexParam: 'My String'
    },
    raw: {
        data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
        topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
    },
    event: 'MyEvent',
    signature: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
    blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
    blockNumber: 1234,
    address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
}

events.allEvents

描述:此方法类似于 events 调用,filter 属性可过滤这些事件。

myContract.events.allEvents([options][, callback])

getPastEvents

参数值:

  • event - String:合约中事件名称
  • options - Object:
    • filter - Object:根据索引过滤事件
    • fromBlock - Number:事件开始的区块,默认值为 latest
    • toBlock - Number:事件截止的区块
    • topics - Array:手动设置过滤事件的主题。
  • callback - Function:事件日志作为返回,错误信息作为第一个参数。

返回值:Promise:先前事件组成的数组对象。

示例:

myContract.getPastEvents('MyEvent', filter, function(error, events){
    console.log(events);
})
.then(function(events){
    console.log('events: ' + events); // same results as the optional callback above
});

> [ { address: '0x7cd2688FA83b64AE13ee45d21b9b261dae9fdF54',
      blockNumber: 787653,
      transactionHash:
       '0xe6547061aaf37a31a2556181918fff498b66a56a9715a0fdf5c0a25f36c06342',
      transactionIndex: 1,
      blockHash:
       '0x7926c4fdbcc445a9e6a401be763b21311d5d0dc58d9eb023c5653bc48edcc948',
      logIndex: 0,
      removed: false,
      id:
       'log_0x3b939928232af4da2bb7fc5b7f5519f223b7ac5f59bb716d8c73d9b19191b3ca',
      returnValues:
       { '0': '5', '1': '6', '2': '11', m: '5', n: '6', result: '11' },
      event: 'MyEvent',
      signature:
       '0x3e238cd42ac2d6f8cb4448b4a931fd3bbd6f1088c845eec9c9daef375f6c908c',
      raw:
       { data:
          '0x00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000b',
         topics: [Array] } 
   },{
    ...
}]