directory
  • Smart Contracts
  • Smart Contract Examples
  • Contract programming mode COP
  • Contract syntax
  • Difficult point
  • Restrictions and specifications
  • Contract architecture

What is a smart Contract

A smart contract is a set of digitally defined promises that include agreements on which parties can enforce those promises. A contract consists of a set of code (the contract’s functions) and data (the contract’s state) and runs on the Ethereum virtual machine.

Using 256-bit machine code, the Ethereum Virtual Machine (EVM) is a stack-based virtual machine used to execute Ethereum smart contracts. As EVM is designed for the Ethereum system, it uses the Ethereum Account Model for value transmission.

What are the capabilities of the contract code:
Read the transaction data. Reads or writes to the contract's own storage space. Read environment variables [block height, hash value, GAS] to send an "inside transaction" to another contract.Copy the code
Architecture in the blockchain platform

Architecture of the blockchain platform

1. What is solidity

Solidity is a smart contract high-level language that runs on top of the Ethereum virtual machine (EVM).

Solidity language features

Its syntax is close to Javascript and it is an object-oriented language. But as a truly decentralized contract that runs on the web, there are a number of differences:

  • Exception mechanism, similar to atomicity of transactions. In the event of an exception, all execution will be pulled back, mainly to ensure atomicity of contract execution and avoid data inconsistency in the intermediate state.
  • The runtime environment is on a decentralized network that emphasizes the way a contract or function is invoked. Because a simple function call becomes code execution on a node on a network
  • Storage is done using a blockchain on the network, where every state of the data can be stored permanently.

2. Development tools

  • The online compiler Remix
  • Visual Studio Code + Soliidty plugin

3 Quick Start

3.1 An Example

Complete steps:

1. Write the contract 2. Compile the contract 3Copy the code

For example

Refer to procedure
$ git clone "https://github.com/cristicmf/bcos-qucik-start-demo"
$ cd startDemo
$ npm install
$ babel-node index.js
Copy the code
File Structure Description
StartDemo ├── ReadMe.md ├─ SimpleStartDemo.sol# Contract code├ ─ ─ codeUtils. Js ├ ─ ─ config. Js# Config file├ ─ ─ index. Js# Deploy contract and test contract├ ─ ─ the outputThe output of # abi /bin/address│ ├── exercises │ ├── exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercisesCopy the code

Detailed code

Pragma solidity ^ 0.4.2; contract SimpleStartDemo { int256 storedData; event AddMsg(address indexed sender, bytes32 msg); modifier only_with_at_least(int x) {if(x >= 5) { x = x+10; _; }}function SimpleStartDemo() {
            storedData = 2;
        }
    
        function setData(int256 x) public only_with_at_least(x){
            storedData = x;
            AddMsg(msg.sender, "[in the set() method]");
        }
    
        function getData() constant public returns (int256 _ret) {
            AddMsg(msg.sender, "[in the get() method]");
            return_ret = storedData; }}Copy the code

3.2 Deployment Contract

For example, get demo

$ babel-node index.js
Copy the code

1. Compile the contract

    execSync("solc --abi  --bin   --overwrite -o " + config.Ouputpath + "  " + filename + ".sol");
Copy the code

2. Deploy the contract to the blockchain

   var Contract = await web3sync.rawDeploy(config.account, config.privKey, filename);
Copy the code

3. Read and write the contract

var address = fs.readFileSync(config.Ouputpath + filename + '.address', 'utf-8'); var abi = JSON.parse(fs.readFileSync(config.Ouputpath /*+filename+".sol:"*/ + filename + '.abi', 'utf-8')); var contract = web3.eth.contract(abi); var instance = contract.at(address); Var data = instance.getData(); Var func = "setData(int256)"; var params = [10]; var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, address, func, params);Copy the code

3.2.1 Concept introduction:

Address: The length of an Ethereum address, with a size of 20 bytes and 160 bits, so it can be encoded using one uint160. Address is the basis of all contracts, all contracts will inherit the address object, can also be an address string, the corresponding code to call at any time. The address of the contract is calculated based on the random number of the account and the hash of the transaction data

ABI: A message format in Ethereum that is called between contracts or when a message is sent. Define the operation function signature, parameter code, return result code, etc.

Transactions: A “transaction” in Ethereum is a signed packet that stores messages sent from an external account.

The simple idea is that whenever a blockchain is written, a transaction will happen.

Transaction receipt:

The return value after a transaction has occurred

3.2.2 Extended Reading:

  • Ethereum-Contract-ABI
  • Solidity-Features
  • Ethereum White paper

3.3 Introduction to the Contract File Structure

1. Version declaration

Pragma solidity ^ 0.4.10;Copy the code

1. Reference other source files

The import "filename"; // Global importCopy the code

1. State Variables

    int256 storedData;
Copy the code

See below for details

2. The Functions (Functions provides)

   function setData(int256 x) public {
         storedData = x;
         AddMsg(msg.sender, "[in the set() method]");
     }
   
    function getData() constant public returns (int256 _ret) {
        return _ret = storedData;
     }
Copy the code

3.

// Declare event AddMsg(Address indexed Sender, bytes32 MSG); Function setData(int256 x) public {storedData = x; AddMsg(msg.sender, "in the set() method"); }Copy the code

4. Structs Types

contract Contract { struct Data { uint deadline; uint amount; } Data data; function set(uint id, uint deadline, uint amount) { data.deadline = deadline; data.amount = amount; }}Copy the code

5. Function Modifiers

Hook modifier only_with_at_least(int x) {if (x >= 5) {x = x+10; _; }}

4. Contract programming mode COP

Conditional Oriented Programming (COP) is a subdomain of contract-oriented programming as a hybrid of functional and imperative programming. COP solves this problem by requiring the programmer to enumerate all the conditions explicitly. The logic becomes flat without conditional state changes. Conditional fragments can be properly documented, reused, and inferred from requirements and implementations. Importantly, COPS treat preconditions as first-class citizens in their programming. Such a pattern specification can ensure the security of the contract.

4.1 the FEATURES

  • The function body has no conditional judgment

Example:

contract Token { // The balance of everyone mapping (address => uint) public balances; // Constructor - we're a millionaire! function Token() { balances[msg.sender] = 1000000; } // Transfer `_amount` tokens of ours to `_dest`. function transfer(uint _amount, address _dest) { balances[msg.sender] -= _amount; balances[_dest] += _amount; }}Copy the code

After the improvement:

function transfer(uint _amount, address _dest) {
    if (balances[msg.sender] < _amount)
        return;
    balances[msg.sender] -= _amount;
    balances[_dest] += _amount;
}
Copy the code

The style of the COP

modifier only_with_at_least(uint x) {
    if (balances[msg.sender] >= x) _;
}

function transfer(uint _amount, address _dest)
only_with_at_least(_amount) {
    balances[msg.sender] -= _amount;
    balances[_dest] += _amount;
}
Copy the code

Read more:

  • Condition-Orientated Programming
  • Paper

5. Introduction to grammar

See the official API for basic syntax

5.1 value type


  • Booleans true false Operator supported by Boolean

    ! Logic of logic && and | | = = equal to or logical! = is not equal to

  • Integer int/uint: signed or unsigned Integer of variable length. The variable supports steps in increments of 8 from uint8 to uint256 and int8 to INT256. Note that by default uint and int represent uint256 and int256

  • Address: The length of an Ethereum Address is 20 bytes in size and 160 bits, so it can be encoded using a uint160. Address is the basis of all contracts, all contracts will inherit the address object, can also be an address string, the corresponding code to call at any time

  • Fixed Byte Arrays

  • Rational and Integer Literals, String Literals

  • Enumeration Types (Enums)

  • Function (Function Types)

5.2 Reference Types

  • Array of bytes of indefinite length (bytes)
  • String (string) bytes3a = “123”;
  • Array
  • Structure (Struts)

6. Important concepts

6.1 Data location for Solidity

The type of data location

The store location property of a variable. There are three types, memory, storage and CallData.

  • Memory is stored in a similar location to our normal program memory. That is allocated, that is used, that is beyond scope, that is unreachable, that is waiting to be reclaimed –
  • Storage variables, data will always exist on the blockchain.
  • Calldata data location is special. Generally, only the parameters of the external function (excluding the return parameters) are forced to be callData

Storage-the Storage model of the state variables

Variables of fixed size (all types except maps, variable length arrays) are sequentially arranged in storage, starting at position 0. If multiple variables occupy less than 32 bytes, they are packed into a single storage slot as much as possible. The rules are as follows:

  • The first item in the storage slot is lower-order aligned.
  • The basic type stores only the required bytes.
  • If the base type cannot fit into the remaining space in one slot, it will be put into the next slot.
  • Structures and arrays always use a new slot and take up the entire slot (but each item in the structure body or array still follows the above rules)

Optimization suggestions:

To facilitate EVM optimization, try to consciously order the variables and members of the structure of the storage so that they can be packed closer together. For example, define uint128, uint128, uint256 in this order, not uint128, uint256, uint128. The latter occupies three slots.

Memory – Layout in Memory

Solidity has 3 32 byte slots reserved:

0-64: Scratch space for hashing methods

64-96: Currently allocated memory size (also known as free Memory pointer)

Staging space can be used between statements (such as during inline compilation)

Solidity always creates a new object where the free memory pointer is, and the corresponding memory is never freed (this may change in the future).

Some operations in Solidity require more than 64 bytes of temporary space, thus exceeding the reserved temporary space. They will be allocated where the free memory pointer is, but due to their relatively short lifetime and the fact that the pointer itself cannot be updated, memory may or may not be zerod out. Therefore, one should not assume that free memory is necessarily zeroed out.

example

6.2 the address

The length of an Ethereum address is 20 bytes in size and 160 bits, so it can be encoded using a Uint160. Address is the basis of all contracts, all contracts will inherit the address object, can also be an address string, the corresponding code to call at any time

6.3 the event

event AddMsg(address indexed sender, bytes32 msg);

  • This line of code declares an “event.” Clients (and server-side applications as well) can listen for events triggered by the blockchain at very low overhead

Events are a handy tool to use the built-in functionality of EVM logging, which can in turn call Javascript callback to listen for events in the DAPP interface.

var event = instance.AddMsg({}, function(error, result) { if (! error) { var msg = "AddMsg: " + utils.hex2a(result.args.msg) + " from " console.log(msg); return; } else { console.log('it error') } });Copy the code
  • Events are inheritable in a contract. When invoked, trigger parameters are stored in the transaction’s log (a special data structure on the blockchain). These logs are associated with the address of the contract, incorporated into the blockchain, and exist for as long as the block is accessible (at least Frontier, Homestead, but perhaps Serenity too). Logs and events are not directly accessible within the contract, even the contract that created the log.
  • The log location is in nodedir0/log, and special types can be typed for verification

6.4 an array

Arrays can be fixed or variable length arrays. We have the length attribute, which is the current length of the array.

  1. Bytes: A dynamic byte array similar to byte[]

  2. String: A dynamically long UTF-8 encoded character type similar to bytes

  3. bytes1~bytes32

    Generally, the fixed length bytes1~bytes32 is used. When you know the length of the string, you can save more space by specifying the length.

6.4.1 Creating an Array

  1. Uint [] memory a = []

  2. new uint[] memory a = new uint; example

    Pragma solidity ^ 0.4.0; contract SimpleStartDemo{ uint[] stateVar; Function f(){uint[] memory memVar; //VM Exception: invalid opcode //memVar [0] = 100; MemVar = new uint[](2); //VM Exception: invalid opcode //stateVar[0] = 1; StateVar = new uint[](2); stateVar = new uint[](2); stateVar[0] = 1; }}Copy the code

6.4.2 Array properties and methods

Length attribute

You can change the length of a storage array. You can change the length of a memory arrayCopy the code

Push method

Storage variable length arrays can use the push method Bytes can use the push methodCopy the code

example

Pragma solidity ^ 0.4.2; contract SimpleStartDemo { uint[] stateVar; Function f() returns (uint){// statevar.push (1); stateVar = new uint[](1); stateVar[0] = 0; Uint pusharr = statevar. push(1); uint len = stateVar.length; //Member "push" is not available in uint256[] memory outside of storage. //uint[] memory memVar = new uint[](1); //memVar.push(1); return len; }}Copy the code

Subscript: Similar to other languages

6.4.3 the Memory array

  1. If Memory arrays are passed as arguments to a function, only the types supported by the ABI are supported.

  2. The Memory array is an example of a property that cannot be modified to change the size of the array

    Pragma solidity ^ 0.4.2;

    Contract SimpleStartDemo {function f() {// create an array of memory uint[] memory a = new uint;

    //Error: Expression has to be an lvalue. //a.length = 100; } //storage uint[] b; function g(){ b = new uint[](7); // You can modify the array of storage b.length = 10; b[9] = 100; }Copy the code

    }

EVM entry restrictions

Due to the limitations of EVM, dynamic and multidimensional arrays cannot be returned directly through external functions

  1. The stroage array cannot be returned directly. It needs to be converted to a memory return
Struct Rate {int key1; int unit; uint[3] exDataArr; bytes32[3] exDataStr; } mapping(int =>Rate) Rates;function getRate(int key1) public constant returns(int,uint[3],bytes32[3]) {
            uint[3] memory exDataInt = Rates[key1].exDataArr;
            bytes32[3] memory exDataStr = Rates[key1].exDataStr;
            return (Rates[key1].unit,exDataInt,exDataStr);
        }
Copy the code

The business scenario

6.5 the function

The function () {internal (default) | external} constant [returns ()]

6.5.1 Internal and External functions

example

Pragma solidity ^ 0.4.5; contract FuntionTest{ function internalFunc() internal{} function externalFunc() external{} function callFunc(){ // Call internalFunc() internally; // Cannot call an external function from within, resulting in a compilation error. //Error: Undeclared identifier. //externalFunc(); //Member "internalFunc" not found or not visible after argument-dependent lookup in contract FuntionTest //this.internalFunc(); // Use 'this' to call an external function in the' external 'manner this.externalfunc (); }} contract FunctionTest1{function externalCall(FuntionTest ft){// call another contract's external function ft.externalfunc (); // Cannot call another contract internal function //Error: Member "internalFunc" not found or not visible after argument-dependent lookup in contract FuntionTest //ft.internalFunc(); }}Copy the code

Access functions have external visibility. If it is accessed internally, such as directly, you can use it as a variable, but if it is accessed externally, such as this., then it must be called as a function.

example

Pragma solidity ^ 0.4.2; contract SimpleStartDemo { uint public c = 10;function accessInternal() returns (uint){
            return c;
        }
        
        function accessExternal() returns (uint){
            returnthis.c(); }}Copy the code

6.5.2 Function Calls

  • Internal calls that do not create an EVM call, also called a message call
  • An external call, creating an EVM call, initiates a message call

6.5.3 Function Modifiers

Modifiers can be used to easily change the behavior of a function. For example, to check certain preconditions before a function executes. Modifiers are contract attributes that can be inherited and overridden by derived contracts (Override).

example

Pragma solidity ^ 0.4.2; contract SimpleStartDemo { int256 storedData; event AddMsg(address indexed sender, bytes32 msg); modifier only_with_at_least(int x) {if(x >= 5) { x = x+10; _; }}function setData(int256 x) public only_with_at_least(x){
            storedData = x;
            AddMsg(msg.sender, "[in the set() method]"); }}Copy the code

6.5.4 Contract constructor with the same name

  • optional
  • There can be only one constructor
  • Overloading not supported

6.6 Constant

Functions can also be declared constant, which commits itself to not modifying any state on the blockchain.

Normally, when you get data off the chain, you add constant to get

6.7 Inheritance (Inheritance)

Solidity supports multiple inheritance by copying code that includes polymorphism.

The parent class

Pragma solidity ^ 0.4.4; contract Meta { string public name; string public abi; address metaAddress;function Meta(string n,string a){
            name=n;
            abi=a;
        }
       
        function getMeta()public constant returns(string,string,address){
            return (name,abi,metaAddress);
        }
       
        function setMetaAddress(address meta) public { metaAddress=meta; }}Copy the code

A subclass

Pragma solidity ^ 0.4.4; import"Meta.sol";
    contract Demo is Meta{
        bytes32 public orgID; 
    
        functionDemo (string n,string abi,bytes32 id) Meta(n,abi) { orgID = id; }}Copy the code
Simplest contract structure

7. To limit

Based on the limitations of EVM, dynamic content cannot be returned through external functionsCopy the code

please keep in mind

- Fail as early and loudly as possible
- Favor pull over push payments
- Order your functioncode: conditions, actions, interactions - Be aware of platform limits - Write tests - Fault tolerance and Automatic bug bounties - Limit the amount Modular Code - Don't Write all your code from Scratch Timestamp dependency: Do not use timestampsin critical parts of the code, because miners can manipulate them
- Call stack depth limitDon't use recursion, and be aware that any call can failif stack depth limit is reached
- Reentrancy: Do not perform external calls in contracts. If you do, ensure that they are the very last thing you do
Copy the code

8. Pain points in the language itself

1. The limited types supported by the ABI make it difficult to return complex structure types. 3. It is difficult to debug and can only rely on eventlog4. Contract call Contracts can only use fixed-length arraysCopy the code

9. Contract structure

Contract Structure stratification

The simplest architecture

1->1 Contract structure diagram

The logical contract is divided into two layers: the data contract and the logical contract. The logical contract is divided into two layers: the data contract and the logical contract.Copy the code

For more details on the contract structure

Truffle framework

  • trufflesuite

advantage

Everyone uses it, it’s easy to use, and the ecology is more comprehensive than other contractual frameworks

function

  • One-click initializing the development contract project (including configuration)
  • Contract compiling
  • Contract deployment
  • Contract tests
  • Contract Debug

upgrade smart contract

  • upgradable

  • solidity-proxy

  • solution flow looks

  • ContractFactory

  • ether-router

  • bcos

10. References

  • blog.zeppelin.solutions
  • solidity-workshop
  • condition-orientated-programming
  • Blockchain technology
  • ABI
  • The glossary
  • fisco-bcos

11. Explanation of related terms:

  1. The code for the Ethereum contracts is written in a low-level stack-based bytecode language called “Ethereum Virtual Machine code” or “EVM code.” Code consists of a series of bytes, each byte representing an operation.
  2. UTXO: The “state” of the bitcoin system is a collection of all unspent bitcoin that has been mined (technically called “unspent transaction outputs, or UTXO”). Each UTXO has a face value and owner (defined by the 20-byte address that is essentially a cryptography public key [1]). A transaction consists of one or more inputs and one or more outputs. Each input contains a reference to an existing UTXO and a cryptographic signature created by a private key corresponding to the owner’s address. Each output contains a new UTXO added to the state.
  3. Blockchain: Originating from Satoshi Nakamoto’s Bitcoin, blockchain, the underlying technology behind Bitcoin, is essentially a decentralized database. A technical solution that collectively maintains a reliable database through decentralization and distrust.