Truffle official website documentation--interacting with your contract

Introduction

In many cases, we want to interact with our contracts, but many operations require some relatively low-level technical accumulation, and even if you write it yourself (certainly more than one or two commands), you will find that managing these commands It's also quite troublesome---for example, you find that one of your commands or operations has good extensibility, and you plan to extend it, but the damn thing is, you find that the extension conflicts with other commands... Depressed! Truffle noticed the complexity of this problem and integrated related technologies to help you.

read and write data

Ethereum thinks there is a difference between writing data to the network and reading data, and they do that too. In fact, this distinction plays an important role in how you write your application. Generally speaking, writing data is called a transaction , and reading data is called a call . Transactions and calls are handled very differently and have the following characteristics.

  • TRANSACTIONS

       Transactions can be said to fundamentally change the state of the network, and a transaction can be as simple as sending ether to another account, or as complex as executing a contract function or adding a new contract to the network. The characteristic of a transaction is that it writes (or changes) data. Transactions need to spend ether to run, which we call 'gas', and the completion of transactions also takes time (in fact, the current decentralized transactions take a long time, but there are also related technical developments aimed at solving this problem. problems, such as Lightning Network vs. IPFS, etc.). On the other hand, when you execute a function in a contract through a transaction, you cannot receive the return value of the function, because the transaction is not processed immediately. In general, functions executed through a transaction will not return a value; instead, they will return a transaction id. So in general, the transaction:

  1. spend gas (ether)
  2. changed the state of the network
  3. cannot be processed immediately (at least for now)
  4. No return value is exposed (only the id of the transaction)

  • CALLS

       Calls, compared to transactions, are very different. Calls can be used to execute code on the network without permanently changing the data. In contrast to transactions, calls are free to run, their characteristic is to read data. When you execute the contract function by calling, you will receive the return value immediately. So in general, calling:

  1. Free (no gas cost)
  2. Does not change the state of the network.
  3. process it now
  4. There will be return values ​​(hooray!)

Choosing between transactions and calls is as simple as deciding whether to read data or write data.

Introduce abstraction

These contract abstractions from Javascript are equivalent to spreading butter and bread in the process of interacting with Ethereum contracts. In a nutshell, abstraction is wrapping some code to make it easy for us to interact with the contract. To use an analogy, abstraction makes us forget the engine and many gears that execute under the hood. truffle uses its own contract abstraction through the truffle-contract module. The following description is the contract abstraction we are talking about.

It’s still the old saying, it’s a mule or a horse, do we need to take it out for a walk, don’t say it so well, it turns out that it’s rubbish to death. So in order for everyone to better understand the abstraction, we need a contract to explain. With the truffle unbox metacoin command, we can create a MetaCoin contract using an existing template.

First enter the command in the console:

mkdir metacoin

cd metacoin/

truffle unbox metacoin

Like this picture below:


If my picture appears, it means that you have succeeded in this step, and then enter the command:

atom ./

It will jump to our atom software. As shown in the figure:


In the image above, we can see the entire metacoin structure from the left.

The code area on the right is the following code (except that I translated the English comments, haha)

pragma solidity ^ 0.4.2;

import "./ConvertLib.sol";

// This is just a simple example of a coin-like contract.
// It's not standard compliant, so don't expect it to communicate with ether.
// coin/token contracts. If you want to create a standard compliant
// Tokens, see: https://github.com/ConsenSys/Tokens. Thanks!

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];
    }
}

This contract contains three methods ( sendCoin getBalanceInEth , and  getBalance ) without a constructor (contracts generally have constructors), and all three methods can be executed as transactions or calls.

(Skip the compile and migrate phases -- I won't talk about this part , open the truffle console )

With truffle we get a Javascript object called MetaCoin

Like the following code:

// print the deployed MetaCoin "version"
// It should be noted that we need a commitment to get the MetaCoin version, enter:
// The following instance is our contract object
MetaCoin.deployed().then(function(instance) {
  console.log(instance);
});

// will output:
//
// Contract
// - address: "0xa9f441a487754e6b27ba044a5a8eb2eec77f6b92"
// - allEvents: ()
// - getBalance: ()
// - getBalanceInEth: ()
// - sendCoin: ()
// ...

Note that the abstraction contains the exact same functions that exist in our contract. It also contains an address, which is the address of our contract (the purple hash address).


execute contract method

Using these abstractions, you can easily execute the methods contained in the contract on the Ethereum network (in fact, networks other than the mainnet can also).

  • make a deal

       We know that in the MetaCoin contract we have three methods that can be executed. If you analyze it carefully, you will find that sendCoin is the only way to write data and change data. The purpose of this method is to send Meta coins from one account to another.

       When we call the method, we will treat such an operation as a transaction . In the following example, we will send 10 Meta coins from one account to another, in a way that continuously changes the network.

var account_one = "0x1234..."; // an address
var account_two = "0xabcd..."; // another address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;
  return meta.sendCoin(account_two, 10, {from: account_one});
}).then(function(result) {
  // If this callback function is called, the transaction is successful.
  alert("Transaction successful!")
}).catch(function(e) {
  // There is an error! needs to be processed.
})

        There are some interesting things in the above code:

  1. We directly call the abstract sendCoin function. This will by default generate a transaction ( ie, write data) rather than a call (call).
  2. When the transaction is successful, the callback function will not be fired until the transaction is processed. This makes life easier and means you don't have to check the status of your transactions yourself.
  3. We passed an object as the third parameter of the sendCoin function. But we also noticed that there is no third parameter in the sendCoin function at all. What you see above is a special object that can always be passed as the last parameter to a function that allows you to edit the specific details of the transaction. Here, we set the from address to ensure that the transaction is from account_one .

  • make a call

       Let's move on, noting that the getBalance function is a good way to read data from the network. It doesn't need any changes as it just returns the MetaCoin balance of the address passed to it. So let's try it out:

var account_one = "0x1234..."; // an address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;
  return meta.getBalance.call(account_one, {from: account_one});
}).then(function(balance) {
  // If this callback function is called, the call is successful.
  // Note that this return is immediate, immediate, without waiting.
  // Let's print the return value.
  console.log(balance.toNumber());
}).catch(function(e) {
  // There is an error! needs to be processed.
})

       Some interesting things:

  1. We must explicitly execute the .call() function in order to let the Ethereum network know that we do not intend to save any changes.
  2. Instead of the id of the successfully run transaction, we get a return value. Note that since the ethernet can handle very large numbers, we create a BigNumber object that can be converted to a number.  

Warning: we cast the return value to a number because in this example the number is small. However, if you try to convert a BigNumber larger than the largest integer supported by Javascript , you will most likely encounter errors or unexpected prompts.

  • Capture Events

       Your contract can trigger events, and by capturing these events, we can better understand what the contract is doing. The easiest way to handle events — is to handle the result object of the transaction that triggered the event , for example:

var account_one = "0x1234..."; // an address
var account_two = "0xabcd..."; // another address

var meta;
MetaCoin.deployed().then(function(instance) {
  meta = instance;  
  return meta.sendCoin(account_two, 10, {from: account_one});
}).then(function(result) {
  // The result is an object with the following values:
  //
  // result.tx => transaction hash, string.
  // result.logs => Array of decoded events fired in this transaction.
  // result.receipt => The object accepted by the transaction, including the gas spent.

  // We can loop over the results. See if a transfer event is triggered.
  for (var i = 0; i < result.logs.length; i++) {
    var log = result.logs[i];

    if (log.event == "Transfer") {
      // We found the event!
      break;
    }
  }
}).catch(function(err) {
  // There is an error! needs to be processed.
});

  • Process transaction results

      When you make a transaction, you get a result object that will give you a lot of information about the transaction. Specifically, you can get the following:


  1. result.tx (string)  - Transaction hash
  2. result.logs (array) - decoded events (logs)
  3. result.receipt (object) - transaction receipt

If you want to learn more, see the README in the truffle-contract project .

  • Add a new contract to the network 

      In the case described above, we have been using the already deployed contract abstraction. We can deploy our own version to the network using the .new() function:

MetaCoin.new().then(function(instance) {
  // print the new address
  console.log(instance.address);
}).catch(function(err) {
  // There is an error! needs to be processed.
});

  • Use the contract at a specific address

     If you already have an address for a contract, you can create a new abstraction to represent the contract for that address.

var instance = MetaCoin.at("0x1234...");

  • Send ether to a contract

      You might just want to send ether directly to the contract, or trigger the contract's  fallback function . You have two options to achieve this.

      Option 1: Send a transaction directly to the contract via instance.sendTransaction() . This is like all available contract instance functions, with the same API as web3.eth.sendTransaction , but without callbacks. If not specified, the to value will be filled automatically .

instance.sendTransaction({...}).then(function(result) {
  // Same transaction result object as above.
});

      Option 2: There is also a simplified version of sending ether directly    

instance.send(web3.toWei(1, "ether")).then(function(result) {
  // Same result object as above.
});

extension

The contract abstraction provided by Truffle contains a large number of utilities that allow you to easily interact with contracts. Check out the truffle-contrac documentation for tips, tricks, and insights.

(official hope)

                      Want to make this page better?  Edit here →



Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327071529&siteId=291194637