In this blockchain 100 lecture, we’ll cover an even simpler way to deploy smart contracts: Truffle.

1

What is Truffle?

Truffle is a development framework for the Ethereum-based Solidity language. Itself based on Javascript. Truffle provides ethereum with a development environment, a testing framework, and an asset pipeline designed to make Ethereum development easier. Using Truffle you get:

Built-in smart contract compilation, linking, deployment, and binary bytecode management.

Automated contract testing for rapid iterative development.

Scriptable, extensible deployment and migration framework.

Network management for deployment to any number of public and private networks.

Use EthPM and NPM for package installation management.

Interactive console for direct contract communication.

Configurable build pipeline that supports continuous integration.

External script runners can execute scripts in the Truffle environment.

Deployed (); Contract Abstraction interface provided. Var Instance = storage.deployed (); Once you have the contract object, you can manipulate the corresponding contract function directly in Javascript.

The principle is to use the Ether Pudding tool package based on Web3. js. Simplify the development process.

Provides the console, after using the framework to build, you can directly call the output results in the command line, can greatly facilitate the development and debugging.

When developing Truffle based applications, we recommend using EthereumJS TestRPC. It’s a complete blockchain that runs in memory, only on your development device.

It returns in real time as trades are executed, rather than waiting for the default block time, so you can quickly validate your newly written code and get instant feedback when errors occur. It is also a powerful client that supports automated testing. Truffle takes full advantage of its features to speed up test run times by nearly 90%. It is best to test these clients thoroughly with TestRPC clients before using them. These are complete client implementations, including mining, networking, block and transaction processing, to which Truffle can be published without additional configuration.

Let’s start with a simple example of Truffle.

2

Install the Truffle

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$NPM install -g [email protected]</pre>Copy the code

When the installation is complete, execute the following command to ensure that Truffle is installed correctly:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$truffle truffle v3.4.11 - a development Frameworkfor Ethereum

Usage: truffle <command> [options]

Commands:
init     Initialize new Ethereum project with example contracts and tests
compile   Compile contract source files
migrate   Run migrations to deploy contracts
deploy   (alias for migrate)
build     Execute build pipeline (if configuration present)
test     Run Mocha and Solidity tests
console   Run a console with contract abstractions and commands available
create   Helper to create new contracts, migrations and tests
install   Install a package from the Ethereum Package Registry
publish   Publish a package to the Ethereum Package Registry
networks Show addresses for deployed contracts on each network
watch     Watch filesystem for changes and rebuild the project automatically
serve     Serve the build directory on localhost and watch for changes
exec     Execute a JS module within this Truffle environment
unbox     Unbox Truffle project
version   Show version number and exit

See more at http://truffleframework.com/docs</pre>
Copy the code

3

Create and initialize the project

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ mkdir myproject

$ cd myproject

$ truffle init</pre>
Copy the code

The directory structure after initialization is as follows:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;""> < p style =" text-decoration: none; clear: none 1_initial_migration. Js │ ├─ 2_deploy_contracts. Js ├──test│ ├─ ├─ ├─ ├─ ├.txt </pre>Copy the code

Contracts / – Where we prepare contracts.

Migrations / – Stores migration deployment scripts.

Test / – Stores the contract test scripts

Truffle. js-truffle configuration file

Truffle Init will give us a token application called MetaCoin. We’ll remove the default application, and we’ll write our own contract.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> $cd myproject

# Delete token contracts

$ rm contracts/ConvertLib.sol

$ rm contracts/MetaCoin.sol

Delete the migration script

$ rm migrations/2_deploy_contracts.js

Delete the test script

$ rm test/TestMetacoin.sol

$ rm test/metacoin.js</pre>
Copy the code

4

Create a contract

Next we create our own contract, go to the contracts directory and create the storage.sol contract file.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> $cd contracts/
$ touch Storage.sol</pre>
Copy the code

The contents of the storage. sol contract are as follows:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> pragmasolidity ^ 0.4.8; contractStorage{ uint256storedData; functionset(uint256data) { storedData=data; } functionget() constantreturns(uint256) { returnstoredData; } }</pre>Copy the code

5

Compile the contract

Next, use the truffle compile command to compile the storm.sol contract you just completed

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ truffle compile

Compiling ./contracts/Migrations.sol...
Compiling ./contracts/Storage.sol...
Writing artifacts to ./build/contracts</pre>
Copy the code

From the console output, we can see that contract-compiled files, which are critical to the proper working of the Truffle framework, are written to the./build/contracts directory. Do not modify these files manually, because even if you do, they will be overwritten when you run the compile command again.

By default, Truffle only compiles contracts that have been modified since the last compilation, in order to reduce unnecessary compilation. If you want to compile the entire contract, use the –all option.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ truffle compile --all</pre>
Copy the code

After compiling the contract, we need to deploy the storage.sol contract, which is deployed in Truffle using a migration script. Let’s go to the Migrations directory and create a migration script for the Storage contract.

6

The migration script

Migration scripts are made up of Javascript files that help you publish contracts to the Ethereum network. Migration scripts are needed because your deployment requirements change over time. As your project evolves, you can create new migration scripts to deploy these changing contracts to the blockchain. Your migration history is recorded on the blockchain by a special Migrations. Sol contract, which will be described in more detail later.

Script naming rules: file names start with a number and end with a descriptive suffix. A numeric prefix is required to record whether the migration was successful. Suffixes are only intended to improve readability for easy comprehension.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> $cd migrations
$ touch 2_storage_migration.js</pre>
Copy the code

File: 2 _storage_migration. Js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varStorage=artifacts.require("Storage");
module.exports=function(deployer) { deployer.deploy(Storage); }; </pre>Copy the code

1. artifacts.require()

At the beginning of the migration script, we tell truffle that we are going to interact with that contract through the artifacts.require() method. This method is similar to require in NodeJs, but in this case it returns a contract abstraction that we can use in the rest of our migration script. The name used in artifacts.require() does not have to be the same as the filename of the contract source file; instead, it should be the same as the name of the contract class defined in the contract source code.

2. module .exports

At the end of the migration script, we pass a function through module.exports, and any function exported by the migration script should accept a deployer object as its first parameter. Helper functions in deployer objects provide a clear syntax during deployment for deploying smart contracts and performing common tasks such as saving published objects for later use. This Deployer object is the main interface to the deployment task, and its APIS are explained later in this article.

Now that we have everything ready, we can deploy storage.sol to our blockchain. In the previous chapter we deployed smart contracts to the Geth private chain, this time we will deploy smart contracts to the Testrpc environment.

If you have not already installed Testrpc, execute the following installation command:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ npm install -g ethereumjs-testrpc</pre>
Copy the code

Start the testrpc

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"EthereumJS testrPC V4.0.1 (ganache-core: 1.0.1) Available Accounts = = = = = = = = = = = = = = = = = = 0 (0) x9d02c028e7dd237213bd181cdb55f98da9ed8e64 (1) 0x0d157f5d9da61893093ba39fad87d08e6c55fc41
(2) 0xd69f903709b80f4ff9b338c725135ff8b7a55b94
(3) 0x5174fb1b516e75428cc1c9fa62e6df3b8313d280
(4) 0xafa676d65111e5ea1790981ca7ccbcf4e1fd37c2
(5) 0x454f7d978cdc588b0932614e512d8570b376aa17
(6) 0x4f8bd67351a54785534133a4b299e4fe402b3438
(7) 0x02d039305aa3628ab7f0cff7f9d7e4e90ff2a331
(8) 0xeace265c6f9153b66e2ce49a34d7a8f39a9223f1
(9) 0xcf396939dc0e067c0c95b5e11808903de62aa11a

Private Keys
==================
(0) 95b6dac199323d4246ce8f13277b85fa94918b17f1271f1b3bee9a2b8e653118
(1) 3567fe613afe8e122cc785b8331907fd21e050eb3144203576d58d37026c9f21
(2) 67eacb4cf7ef07171443e29101cfcb369f7bee2b1ae4c6145c20719e88e7458d
(3) e6ea7cbbcb4e4014738dcdb093f0a8be9fee67c189e18e5f1baf384e05cbe525
(4) b151fbd620ee6a7fea833c8017b181a431d49a9c7e2a777d1ba5e6127b39f909
(5) 6765223734c785fbedce37e16786f7ab79fdd697933e27b4663bd72e5dd29b01
(6) 2d3ade35f2ecec67834fa2b08ab8935d0b4d8b704c41cef8ced9fa24475d7ee4
(7) 385edb489851649f6200621b4338121a7eebead8c05d5f50c036da59b8695a9a
(8) a412e30d941f9015d58bf27f335e90639e1b67cea9c3442ff64dbec58733ba04
(9) e0fd135471034fb5b2e6f494ad3947be012f15d2d08f26985f9bcc52e47e003f
Copy the code

HD Wallet

Mnemonic:     million remember shell basket verify because image mobile extra novel rival purchase
Base HD Path: m/4460 '/'/ 0'/0/{account_index} Listening on localhost:8545Copy the code

After testrPC is successfully started, go back to the directory of myProject and run the migration command

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ truffle migrate

Using network 'development'. Running migration: 1_initial_migration.js Deploying Migrations... . 0x9660bd2dad09d2417ab2d0d7931395d4425c857e09dca4cba37850229ea12004 Migrations: 0xe78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab Saving successful migration to network... . 0xbb4949bdd34ff8085babe7e8624b67834f79b8d287b131c79000be7163697932 Saving artifacts... Running migration: 2_deploy_Storage.js Deploying Storage... . 0x33448d46fd119b46b9a49ba6550becee7266f9f02ad48561afca93bf4e13e912 Storage: 0xcfeb869f69431e42cdb54a4f4f105c19c080a601 Saving successful migration to network... . 0x8e1f6cf2cf9221b6242de54995c6e71e0ae69781a6b4b587a98e3b3ae5acd047 Saving artifacts... </pre>Copy the code

The truffle Migrate command executes all migration scripts that reside in the Migrations directory. If you have successfully executed migration scripts before, Truffle Migrate will only perform newly created migrations. Without a new migration script, this command does nothing. You can re-execute the entire migration script using the option –reset.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">$ truffle migrate --reset</pre>
Copy the code

3. Initialize the migration contract

We mentioned a particular Migrations. Sol contract at the beginning of this section, so let’s take a closer look at this particular contract. In order to use the migration function, Truffle requires that you have a migration contract. This contract must contain a specific interface, and for most projects, this contract will only be deployed during the first migration and will not be changed. When you use Truffle Init to create a project, it creates this contract by default.

File name: contracts/ migration.sol

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> pragmasolidity ^ 0.4.4; contractMigrations{ addresspublicowner; uintpubliclast_completed_migration;modifierrestricted() {
   if(msg.sender==owner) _;
}

 functionMigrations() {
   owner=msg.sender;
}

 functionsetCompleted(uintcompleted) restricted{
   last_completed_migration=completed;
}

 functionupgrade(addressnew_address) restricted{
   Migrationsupgraded=Migrations(new_address);
   upgraded.setCompleted(last_completed_migration);
}
}</pre>
Copy the code

To take advantage of Migration features, you must first deploy the migration. sol contract. To do this, create the following migration script:

File name: migrations/1_initial_migrations.js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varMigrations=artifacts.require("./Migrations.sol");

module.exports=function(deployer) { // Deploy the Migrations contract as our only task deployer.deploy(Migrations); }; </pre>Copy the code

To deploy other contracts, you can increment the number prefix to create a new migration script.

4. Deployer (Deployer)

Your migration script will use this deployer object to organize the deployment tasks. Deployer objects perform deployment tasks synchronously, so you can write deployment tasks sequentially.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">// deploy A and B deployer.deploy(A); deployer.deploy(B); </pre>Copy the code

In addition, each function on Deployer returns a promise that queues deployment tasks with execution order dependencies.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">// Deploys A and deploys B, and sends the address of A to B deployer.deploy(A). Then (function () {
returndeployer.deploy(B, A.address); }); </pre>Copy the code

5. deployer API

The Deployer objects contain many methods that you can use to simplify your migration efforts.

(1) deployer. Deploy (CONTRACT, ARGS… , OPTIONS)

This API is used to deploy contracts. The contract argument is passed in the name of the contract to be deployed, the args argument is passed in the argument required by the constructor of the contract, and options is an optional argument whose value is {overwrite: True /false}, if overwrite is set to false, then deployer does not deploy the contract when the contract has already been deployed, this is useful when the dependencies of a contract are provided by an external contract address.

To quickly deploy multiple contracts, you can check with deployer.deploy(…..) The function passes in one or more arrays.

Example:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">// Deployer.deploy (A); Deployer.deploy (A, arg1, arg2,...) ; Deployer.deploy ([[A, arg1,]) deployer.deploy([[A, arg1,]) arg2, ...], B, [C, arg1] ]); // Examples of external dependencies: // // overwrite:false// If SomeDependency contract is running on our own test chain, or there is no SomeDependency contract running on the chain, // Overwrite:falseTo overwrite:true, indicating that SomeDependency has not been deployed before. deployer.deploy(SomeDependency, {overwrite:false}); </pre>Copy the code

(2) Deployer.Link (LIBRARY, DESTINATIONS)

Link a deployed library to one or more contracts. Destinations can be passed in to a single contract or a combination of contracts. If a contract in Destinations doesn’t depend on the library, the Link function of Deployer ignores that contract.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">// Deploy library LibA and link LibA to contract B and deploy contract b. deployer.deploy(LibA); deployer.link(LibA, B); deployer.deploy(B); // Deployer.link (LibA, [B, C, D]); </pre>Copy the code

(3) deployer.then(function() {… })

It can be used during migration to call contract-specific functions to deploy new contracts, do some initialization for deployed contracts, and so on.

Example:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">vara, b;
deployer.then( function() {// Deploy A new version of contract A to the networkreturnA.new();
}).then( function(instance) { a=instance; // Get the deployed instance of contract BreturnB.deployed();
}).then( function(instance) { b=instance; // Use contract BsetThe A() method sets A new instance of A's address. }); </pre>Copy the code

(4) Network related

At migration time, the migration script will pass you the networks configured in truffle.js, which you can accept as the second argument in the module.exports export function.

File: truffle. Js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">module.exports = {
networks: {
  development: {
    host: "localhost",
    port: 8545,
    network_id: "*"// Match any network id } } }; </pre>Copy the code

Example:

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">module.exports=function(deployer, network) {
 if(network=="live") {// When not present"live"When on the network, do some specific operations.else{// Do something else while it's on.}}</pre>Copy the code

(5) Available accounts

When the migration is performed, the migration script passes you a list of accounts available in the current Ethereum client or web3.provider, which is exactly the same as the account list returned by web3.eth.getAccounts(). You can accept this value in the third argument of the module.exports export function.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">module.exports=function(deployer, network, accounts) {// Use accounts in your migration script}</pre>Copy the code

7

Contract interaction

Ethereum distinguishes between writing data to the Ethereum network and reading data from it. Generally speaking, writing data is called a transaction and reading data is called a call. Transactions and invocations are handled very differently and have the following characteristics.

1. Transaction

Trading fundamentally changes the state of the web. Simple transactions include sending Ether to another account. Complex transactions include calling a contract function to deploy a contract to the network. The salient features of the transaction are:

Transactions can write or modify data;

Transactions cost ether to run, which is what we call gas;

Transactions take time to process.

When you call the function of the contract through a transaction, we will not get the return value of the smart contract immediately, because the transaction is currently only sent, and it is still some time before it is packaged and executed. Normally, functions executed through a transaction will not return a value immediately, they will return a transaction ID. So to summarize, a transaction generally has the following characteristics:

Consume gas (Ether)

Change the network status

Not immediately processed

Does not immediately return a return value (only a transaction ID)

2. CALL

Invocation, on the other hand, is completely different. The call can execute code on the network but does not permanently change the data. The call can run for free and does not cost gas. The salient feature of the call is that it is used to read data. When you execute a contract function by calling it, you will receive the return value immediately. To summarize, the call is:

Is free (does not consume gas)

Does not change the state of the network

Will be dealt with immediately

Returns a value immediately

The decision to use a transaction or call is simple: to read or write data.

3. Contract abstraction

Contract abstraction is the mid-layer glue that binds Javascript and Ethereum contracts together. In short, contract abstraction encapsulates the code, making it easy for you to interact with the contract so you don’t have to worry about contract invocation details. Truffle uses its own contract abstraction through the truffle-contract module. The function in the contract abstraction is the same as the function in our contract.

To use contract abstraction and contract interaction, we need to install the Truffle-Contract module via NPM

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;"> $cdMyproject $NPM init -y $NPM install --save [email protected] $NPM install --save [email protected]</pre>Copy the code

4. Interact with the contract

(1) Call interaction

With these concepts in mind, we can now interact with the previously deployed storage.sol contract, first invoking the contract as a call.

File: call. Js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varWeb3=require("web3");

varcontract=require("truffle-contract");
vardata=require(".. /build/contracts/Storage.json"); VarStorage =contract(data); varprovider=newWeb3.providers.HttpProvider("http://localhost:8545"); Storage.setProvider(provider); // Deployed with contract abstraction.function(instance) { returninstance.get.call(); }). Then (result=>{console.info(result.tostring ()); //return0}). Catch (err=>{// error! Handle exception information here}); </pre>Copy the code

Note:

We must explicitly call the.call() function to tell the Ethereum network that we are not modifying data on the blockchain.

When the call succeeds, we receive a return value instead of the transaction ID.

(2) Transaction

The storedData variable in the storage. sol contract is set to 42 by transaction.

File: transaction. Js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varWeb3=require("web3");

varcontract=require("truffle-contract");
vardata=require(".. /build/contracts/Storage.json"); VarStorage =contract(data); varprovider=newWeb3.providers.HttpProvider("http://localhost:8545");
Storage.setProvider(provider);

varstorageInstance;
Storage.deployed().then(function(instance) { storageInstance=instance; / / in the transaction way and interactive returnstorageInstance. Set (42, {the from: Storage. Web3. Eth. Accounts [0]}); }).then(result=>{// result is an object that contains the following values: // // result.tx => transactionhash, string // result.logs => events triggered in transaction calls, array type // result.receipt => Transaction receipt object, which contains the number of gas used console.info(result.tx); / / return transaction ID}). Then (() = > {/ Storage/call the get method returnstorageInstance. Get the call (); }).then(result=>{ console.info(result.toString()); // Return 42, indicating that our previous call was successful! }). Catch (err=>{// error! Handle exception information here}); </pre>Copy the code

The code above has a few caveats:

We call the contract-abstract set method directly. By default, this operation sends a transaction to the blockchain network. Can also be explicitly call storageInstance. Set. SendTransaction (42, {the from: Storage. Web3. Eth. Accounts [0]}), showed that after the transaction manner interactions

When the transaction is successfully issued, the callback function is activated only after the transaction has been successfully packaged, saving you the trouble of writing your own judgment statements to check the status of the transaction.

We pass an object to the second argument to the set function. Note: In our storage. sol contract code, the set function does not take a third argument. The third argument is in the contract abstraction API. In all functions of the contract abstraction, you can pass them an object as a final argument in which you can write some transaction details. In this case, we write the FROM field in the object to ensure that the transaction is from web3.eth. Accounts [0].

5. Add a new contract to the network

In all of the examples above, we are using a deployed contract abstraction, and we can use the contract abstraction.new() function to deploy our own contract.

File: new. Js

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varWeb3=require("web3");

varcontract=require("truffle-contract");
vardata=require(".. /build/contracts/Storage.json"); VarStorage =contract(data); varprovider=newWeb3.providers.HttpProvider("http://localhost:8545"); Storage.setProvider(provider); varstorageInstance; / / the new deployment of new contract Storage. New ({the from: Storage. Web3. Eth. Accounts [0], gas: 1000000}). Then (function(instance) { storageInstance=instance; // Output the address of the new contract console.log(instance.address); / / 0 xfc628dd79137395f3c9744e33b1c5de554d94882}). The catch ((err) = > {the console. The info (err) / / an error! Handle exception information here}); </pre>Copy the code

6. Use the existing contract address

If you already have a contract address, you can create a new contract abstraction from that address.

<pre style="margin: 0px 0px 10px; Padding: 9.5 px; border-radius: 4px; background: rgb(245, 245, 245); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; max-width: 100%; color: rgb(51, 51, 51); Letter - spacing: 0.544 px; text-align: justify; overflow: auto; font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; The line - height: 1.42857; word-break: break-all; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-sizing: border-box ! important; word-wrap: break-word ! important;">varWeb3=require("web3");

varcontract=require("truffle-contract");
vardata=require(".. /build/contracts/Storage.json"); VarStorage =contract(data); varprovider=newWeb3.providers.HttpProvider("http://localhost:8545");
Storage.se                    </pre>
Copy the code

Source: Blockchain bros

Source: “Blockchain Development Practice – Ethereum Key Technology and Case Analysis” – China Machine Press

Author: Wu Shouhe

Blockchain 100 Lecture: HiBlock Blockchain Community Cynthia

For reprinting, please apply and indicate the source of the column and the original text.

Online Course Recommendation

[Online course] 4 classes and 8 hours of training, jiang Yong, the author of “Vernacular Blockchain”, will teach you how to quickly master the development of blockchain smart contract

Recommendation of offline activities

Technology workshop | (share) + practice Dapp + 1 day learn to block chain tokens development (xian)

Technology salon | use tamper-proof traceability features, explore the block chain in the application direction of the government and corporate entities (chengdu)