GVKun编程网logo

web3.js_1.x.x--API(二)/合约部署与事件调用(如何部署合约代码)

11

本篇文章给大家谈谈web3.js_1.x.x--API(二)/合约部署与事件调用,以及如何部署合约代码的知识点,同时本文还将给你拓展asp.net-web-api–WebAPI/MVC6中的安全JSO

本篇文章给大家谈谈web3.js_1.x.x--API(二)/合约部署与事件调用,以及如何部署合约代码的知识点,同时本文还将给你拓展asp.net-web-api – Web API / MVC 6中的安全JSON Web令牌、defi质押lp挖矿dapp系统开发合约部署详情、eosio.system智能合约介绍(四)合约部署介绍、Fintoch系统开发智能合约部署dapp开发技术等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

web3.js_1.x.x--API(二)/合约部署与事件调用(如何部署合约代码)

web3.js_1.x.x--API(二)/合约部署与事件调用(如何部署合约代码)

web3.js_1.x.x的使用和网上查到的官方文档有些不同,我对经常使用到的API进行一些整理,希望能帮到大家
转载博客:http://www.cnblogs.com/baizx/p/7474774.html
pragma solidity ^0.5.0;//指定和solcjs中的solidity编译版本一致

contract MyToken {

    /*
    10000,"eilinge",4,"lin"
    msg.sender:0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
    0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db,20
    0x583031d1113ad414f02576bd6afabfb302140225,40
    0xdd870fa1b7c4700f2bd7f44238821c26f7392148,60

    "0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db","0xdd870fa1b7c4700f2bd7f44238821c26f7392148",10
    */
    /* Public variables of the token */
    string public name;
    string public symbol;
    uint8 public decimals;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint)) public allowance;
    mapping (address => mapping (address => uint)) public spentAllowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);
    event ReceiveApproval(address _from, uint256 _value, address _token, bytes _extraData);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    constructor(uint256 initialSupply, string memory tokenName, uint8 decimalUnits, string memory tokenSymbol) public{
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) payable public{
        if (balanceOf[msg.sender] < _value) revert();           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) revert(); // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        emit Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */

    function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)  public returns (bool) {
        allowance[msg.sender][_spender] = _value;
        //emit ReceiveApproval(msg.sender, _value, this, _extraData); //this 在该编译器中无法使用,暂时没有找到正确调用本合约地址
    }

    /* A contract attempts to get the coins */

    function transferFrom(address _from, address _to, uint256 _value) public payable returns(bool) {
        if (balanceOf[_from] < _value) revert();                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) revert();  // Check for overflows
        if (spentAllowance[_from][msg.sender] + _value > allowance[_from][msg.sender]) revert();   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        spentAllowance[_from][msg.sender] += _value;
        emit Transfer(msg.sender, _to, _value);
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () payable external{
        revert();     // Prevents accidental sending of ether
    }
}
solcjs --abi --bin token.sol  -->[eve_sol_MyToken.abi/eve_sol_MyToken.bin]
start truffle:truffle develop //port:9545
var Web3 = require(''web3'');
var fs = require(''fs'');
//var web3 = new Web3(new Web3.providers.IpcProvider("\\\\.\\pipe\\geth.ipc",net));
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545"));
var eth=web3.eth;

/*
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de
*/
var abi = JSON.parse(fs.readFileSync("eve_sol_MyToken.abi"));
var bytecode = fs.readFileSync(''eve_sol_MyToken.bin'');

var tokenContract = new web3.eth.Contract(abi, null, {
    from: ''0xf17f52151ebef6c7334fad080c5704d77216b732'' // 目前web3没有api来解锁账户,只能自己事先解锁
});

/*
truffle(develop)> tokenContract.options
    { address: [Getter/Setter], jsonInterface: [Getter/Setter] }
truffle(develop)> tokenContract.options.jsonInterface[1]
    { constant: false,
      inputs:
       [ { name: ''_from'', type: ''address'' },
         { name: ''_to'', type: ''address'' },
         { name: ''_value'', type: ''uint256'' } ],
      name: ''transferFrom'',
      outputs: [ { name: '''', type: ''bool'' } ],
      payable: false,
      stateMutability: ''nonpayable'',
      type: ''function'',
      signature: ''0x23b872dd'' }
*/
tokenContract.deploy({
    data: bytecode,//bin
    arguments: [32222, ''token on web3'',0,''web3'']
}).send({
    from: ''0xf17f52151ebef6c7334fad080c5704d77216b732'',
    gas: 1500000,
    gasPrice: ''30000000000000''
}, function(error, transactionHash){
    console.log("deploy tx hash:"+transactionHash)//0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd
})
.on(''error'', function(error){
    console.error(error) })
.on(''transactionHash'', function(transactionHash){
    console.log("hash:",transactionHash)})// 0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd
.on(''receipt'', function(receipt){
    console.log(receipt.contractAddress) // contains the new contract address
})
.on(''confirmation'', function(confirmationNumber, receipt){
    console.log("receipt,",receipt)})
    /*
    receipt, { transactionHash: ''0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd'',
      transactionIndex: 0,
      blockHash: ''0x97efd68ca1245db9ef6899589e6a3b1b1e404bd08f5f7467896e9d2b4f03a4c0'',
      blockNumber: 16,
      gasUsed: 1041001,
      cumulativeGasUsed: 1041001,
      contractAddress: ''0x4D2D24899c0B115a1fce8637FCa610Fe02f1909e'',
      status: true,
      logsBloom: ''0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'', events: {} }
*/ .then(function(newContractInstance){ console.log(newContractInstance.options.address) // ''0x30753E4A8aad7F8597332E813735Def5dD395028'' });
var Web3 = require(''web3'');
var fs = require(''fs'');
//var web3 = new Web3(new Web3.providers.IpcProvider("\\\\.\\pipe\\geth.ipc",net));
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545"));
var eth=web3.eth;


var MyTokenABI = JSON.parse(fs.readFileSync("eve_sol_MyToken.abi"));
var addr = ''0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4'';

var tokenContract = new web3.eth.Contract(MyTokenABI, addr);

//合约部署成功以后,有了地址就可以根据地址来查询合约的状态
tokenContract.methods.name().call(null,function(error,result){
        console.log("contract name "+result);//''token on web3''
    })

    //查询合约状态并不需要发起事务,也不需要花费gas
tokenContract.methods.balanceOf("0xf17f52151ebef6c7334fad080c5704d77216b732").call(null,function(error,result){
        console.log("balanceOf "+result);//387
    })
//调用合约函数:合约的函数除了指明返回值是constant的以外,都需要发起事务,这时候就需要指定调用者,因为要花费该账户的gas.
//查询合约状态并不需要发起事务,也不需要花费gas
tokenContract.methods.transfer("0xf17f52151ebef6c7334fad080c5704d77216b732",387).send({from: ''0x627306090abab3a6e1400e9345bc60c78a8bef57''})
.on(''transactionHash'', function(hash){})
.on(''confirmation'', function(confirmationNumber, receipt){})
.on(''receipt'', function(receipt){
    // receipt example
    console.log(receipt); //查询这里可以得到结果
})
.on(''error'', console.error); // If a out of gas error, the second parameter is the receipt.


//刚刚调用transfer的时候还会触发合约的事件Transfer,如果程序关注谁给谁进行了转账,那么就可以通过监听该事件.
/*tokenContract.events.Transfer({
    fromBlock: 0,
    toBlock:''latest''
},function(error, event){
})
.on(''data'', function(event){ //Object: 接收到新的事件时触发,参数为事件对象
    console.log(event); // same results as the optional callback above
})
.on(''changed'', function(event){//Object: 当事件从区块链上移除时触发,该事件对象将被添加额外的属性"removed: true"
    // remove event from local database
})
.on(''error'', console.error);//Object: 当发生错误时触发
*/
/*
{ transactionHash: ''0xb2aff2ac2e95c5f47ca8dc3d97104f0f65346a2c80f5b2dfaa40241276d4110a'',
  transactionIndex: 0,
  blockHash: ''0x405ce50ab7d02620ae2a61579976ebe5a1a466a13cc03ef857324ac66983ab91'',
  blockNumber: 13,
  gasUsed: 36680,
  cumulativeGasUsed: 36680,
  contractAddress: null,
  status: true,
  logsBloom: ''0x00000000000000000000000000000000000000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000008000000010000008000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000010000000001000000000010000000000000000000000000000000000000000010000000002000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'',
  events:
   { Transfer:
      { logIndex: 0,//Number: 事件在块中的索引位置
        transactionIndex: 0,//Number: 事件在交易中的索引位置
        transactionHash: ''0xb2aff2ac2e95c5f47ca8dc3d97104f0f65346a2c80f5b2dfaa40241276d4110a'',//32 Bytes - String: 事件所在交易的哈希值
        blockHash: ''0x405ce50ab7d02620ae2a61579976ebe5a1a466a13cc03ef857324ac66983ab91'',//32 Bytes - String: 事件所在块的哈希值,pending的块该值为 null
        blockNumber: 13,//Number: 事件所在块的编号,pending的块该值为null
        address: ''0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4'',//String: 事件源地址
        type: ''mined'',
        id: ''log_3f0fc629'',
        returnValues: [Object],//Object: 事件返回值,例如 {myVar: 1, myVar2: ''0x234...''}.
        event: ''Transfer'',//String: 事件名称
        signature: ''0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'',//String|Null: 事件签名,如果是匿名事件,则为null
        raw: [Object] } } }
*/

tokenContract.methods.transferFrom(''0x627306090abab3a6e1400e9345bc60c78a8bef57'',"0xf17f52151ebef6c7334fad080c5704d77216b732",20).send({from: ''0x627306090abab3a6e1400e9345bc60c78a8bef57''})
.on(''transactionHash'', function(hash){})
.on(''confirmation'', function(confirmationNumber, receipt){})
.on(''receipt'', function(receipt){
    // receipt example
    console.log(receipt); //查询这里可以得到结果
})
.on(''error'', console.error);

tokenContract.events.Transfer({
    //fromBlock: 0,
    toBlock:''latest''
},function(error, event){
})
.on(''data'', function(event){
    console.log(event); // same results as the optional callback above
})
.on(''changed'', function(event){
    // remove event from local database
})
.on(''error'', console.error);

/*
Error: Returned error: VM Exception while processing transaction: revert
    at Object.ErrorResponse (C:\Users\wuchan4x\node_modules\web3-core-helpers\src\errors.js:29:16)
    at C:\Users\wuchan4x\node_modules\web3-core-requestmanager\src\index.js:140:36
    at XMLHttpRequest.request.onreadystatechange (C:\Users\wuchan4x\node_modules\web3-providers-http\src\index.js:91:13)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:289:61)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickCallback (internal/process/next_tick.js:181:9)
{ transactionHash: ''0xe0e37531928e2b0e5592f954dfe6ae8293f28e322d41256b2b64dd80082c93f7'',
  transactionIndex: 0,
  blockHash: ''0x11b3511ed5269a601af864c74e4946edb56b7ef1f9331868cedf85b7c84cb59e'',
  blockNumber: 14,
  gasUsed: 36680,
  cumulativeGasUsed: 36680,
  contractAddress: null,
  status: true,
  logsBloom: ''0x00000000000000000000000000000000000000000004000000000000000000000000000,
events: { Transfer: { logIndex: 0, transactionIndex: 0, transactionHash: ''0xe0e37531928e2b0e5592f954dfe6ae8293f28e322d41256b2b64dd80082c93f7'', blockHash: ''0x11b3511ed5269a601af864c74e4946edb56b7ef1f9331868cedf85b7c84cb59e'', blockNumber: 14, address: ''0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4'', type: ''mined'', id: ''log_0f1d28ae'', returnValues: [Object], event: ''Transfer'', signature: ''0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'', raw: [Object] } } }
*/

 

asp.net-web-api – Web API / MVC 6中的安全JSON Web令牌

asp.net-web-api – Web API / MVC 6中的安全JSON Web令牌

安全问题:
根据 https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/,许多JWT库使用令牌本身来确定签名的算法.

这是我们的用例:
我们想要创建一个登录机制,使用硬凭证(用户名/密码)验证用户,然后返回一个JWT令牌,例如: 3天的寿命.令牌应包含用户名,签名应保证令牌不能“伪造”.

我们可以在Web API / MVC 6中使用哪些库?重要的是可以在解码时指定签名算法以避免漏洞.

如果可能,我们希望避免集成复杂的OAuth组件.

解决方法

我正在使用System.IdentityModel.Tokens.Jwt库,我刚刚检查了这个问题.我在我的一个测试中生成了一个令牌并验证了它,然后我删除了将alg更改为none的signingCredentials.使用“alg”生成的JWT:“none”验证失败.

以下是我生成令牌的方法:

public string Generatetoken(SSOContext context,SignatureSettings settings)
{
    var token = new JwtSecurityToken(
        issuer: "MyIssuer",audience: "MyAudience",claims: GetClaims(context),//comment the below line to generate a 'none' alg
        signingCredentials: new X509SigningCredentials(settings.Certificate),notBefore: DateTime.UtcNow,expires: DateTime.UtcNow.AddHours(1)
        );

    return new JwtSecurityTokenHandler().Writetoken(token);
}

当我验证令牌时,我得到了一个与消息一样的异常

IDX10504: Unable to validate signature,token does not have a signature:

defi质押lp挖矿dapp系统开发合约部署详情

defi质押lp挖矿dapp系统开发合约部署详情

Uniswap 是去中心化的,不仅跟传统的加密货币交易所不同,也跟普通的去中心化代币交易所不同。Uniswap 是一组部署到以太坊网络的合约,所有的交易都在链上进行。

function addLiquidityETH(

    address token,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline

) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {

    (amountToken, amountETH) = _addLiquidity(
        token,dapp流动性质押挖矿系统开发卫星:hkkf5566
        WETH,
        amountTokenDesired,
        msg.value,
        amountTokenMin,
        amountETHMin
    );

    address pair = UniswapV2Library.pairFor(factory, token, WETH);

     //把coin从合约调用者账户转到币对

    TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);

    //把发送的eth兑换成WETH到swap合约
    IWETH(WETH).deposit{value: amountETH}();

    //swap合约把上一步兑换的weth充值到币对
    assert(IWETH(WETH).transfer(pair, amountETH));

    //添加流动性
    liquidity = IUniswapV2Pair(pair).mint(to);
    // 把发送的多于的eth发回给调用者
    if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
}

首先使用修改器做了一次时间戳校验,传入的时间戳必须大于当前区块的时间戳。

modifier ensure(uint deadline) {
    require(deadline >= block.timestamp, ''UniswapV2Router: EXPIRED'');
    _;
}

然后调用了_addLiquidity

// **** ADD LIQUIDITY ****
function _addLiquidity(
    address tokenA,  //yp
    address tokenB,  // Weth
    uint amountADesired, //yp amount
    uint amountBDesired, // msg.value 
    uint amountAMin, //滑点后
    uint amountBMin  //滑点后
) internal virtual returns (uint amountA, uint amountB) {
    // create the pair if it doesn''t exist yet
    //创建币对
    if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {
        IUniswapV2Factory(factory).createPair(tokenA, tokenB);

        }

    //
    (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB);
    if (reserveA == 0 && reserveB == 0) {
        (amountA, amountB) = (amountADesired, amountBDesired);

    } else {
        uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);
        //计算出来的weth数量小于发送的eth数量
        if (amountBOptimal <= amountBDesired) {
            require(amountBOptimal >= amountBMin, ''UniswapV2Router: INSUFFICIENT_B_AMOUNT'');
            (amountA, amountB) = (amountADesired, amountBOptimal);
        } else {  //大于。
            uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA);
            assert(amountAOptimal <= amountADesired);


            require(amountAOptimal >= amountAMin, ''UniswapV2Router: INSUFFICIENT_A_AMOUNT'');
            (amountA, amountB) = (amountAOptimal, amountBDesired);
        }
    }
}

eosio.system智能合约介绍(四)合约部署介绍

eosio.system智能合约介绍(四)合约部署介绍

01

目的

本文档结合系统合约,介绍了合约部署的核心概念和步骤,包括合约部署过程以及setcode和setabi方法,帮助初学者和开发者快速了解和掌握EOS系统合约部署的相关知识。

02

概述

“eosio.system”智能合约是eos的系统命令合约。这个合约几乎实现了eos全部的系统命令,包括创建账户、资源质押、超级节点投票、域名竞拍等功能,它定义了区块链核心功能所需的结构和操作。

下文将介绍合约部署的相关知识。

03

环境准备

(一)一条正在运行且可访问的区块链

中移链(基于EOS)测试环境搭建

(二)确保本地钱包已打开并解锁

如何创建钱包:

https://developers.eos.io/manuals/eos/latest/cleos/how-to-gui...

04

合约部署介绍

(一)合约部署过程

假设您要将合约部署到的帐户名称是addressbook,请执行以下命令:

cleos set contract addressbook you_local_path_to/addressbook/ -p addressbook@active

命令详解:

set contract:cleos 工具的子命令,用于部署合约

addressbook:要部署合约的账户名称,即目标账户。请将 addressbook 替换为您自己的账户名称

you_local_path_to/addressbook/:合约的本地路径,指定了合约的位置。请将 /your_local_path_to/替换为您本地的实际路径,最好是绝对路径

-p addressbook@active:指定操作的权限。在这种情况下,-p参数后面的addressbook表示使用 addressbook 账户的active权限进行操作。请确保addressbook账户具有足够的权限来部署合约

通过运行这个命令,合约将被部署到addressbook账户。

得到如下结果:

Reading WASM from /home/xxx/biosboot/genesis/test/addressbook/addressbook.wasm...
Publishing contract...
executed transaction: ea09081dc5e42bd1f2b5abe619a7388e1e52ec16a91adb221f3ecb11fa566dde  17840 bytes  16689 us
#         eosio <= eosio::setcode               {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d01000000019a022a60000060037f7f7f01...
#         eosio <= eosio::setabi                {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e32000305657261736500010475736572046e616d...

部署EOSIO合约时,需经历以下步骤:

读取WAST/WASM文件:读取存放在build目录下的WAST/WASM文件,这些文件是要部署的合约的编译结果;

装配WASM:对于读取的WAST/WASM文件,进行装配,将合约的二进制代码准备好供后续操作使用。

将合约发布到区块链上

执行交易(合约也是一个交易),需要执行两个关键动作:

setcode:该动作用于在区块链上部署或更新账户的合约代码。

setabi:该动作用于为通过account名称标识的合约设置ABI(ApplicationBinaryInterface)。尽管在技术上ABI是可选的,但所有EOSIO工具都依赖于它以提供更便捷的合约交互体验。

执行完以上操作后,合约已成功部署到EOS区块链中的addressbook账户上。

从结果可以看出,调用

cleossetcontractaddressbookyou_local_path_to/addressbook/-paddressbook

等价于调用:

cleos push action addressbook setcode ''[addressbook.wasm]'' -p addressbook
cleos push action addressbook setabi ''[addressbook.abi]'' -p addressbook

(二)setcode方法介绍

setcode操作是EOSIO中的一种操作,用于在区块链上部署或更新账户的合约代码。它用于部署或更新与账户关联的智能合约。在使用setcode操作部署或更新合约时,会检查合约是否已经在运行代码。

具体而言,当执行setcode操作时,EOSIO会获取合约的wasm文件,并对其进行处理。在处理过程中,会计算wasm文件的哈希值,以表示该合约的唯一标识。这个哈希值可以用于比对合约的版本和完整性,以确保在部署或更新合约时没有出现错误或篡改。

1、setcode源码介绍

/**
* Set code action sets the contract code for an account.
*
* @param account - the account for which to set the contract code.
* @param vmtype - reserved, set it to zero.
* @param vmversion - reserved, set it to zero.
* @param code - the code content to be set, in the form of a blob binary..
*/
[[eosio::action]]
void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector<char>& code ) {}

参数详解:

account:要部署或更新代码的账户名称

vmtype:此参数保留,应设置为零

vmversion:此参数保留,应设置为零

code:合约代码的二进制表示

2、setcode操作的实现

读取合约的WAST或WASM文件:

合约的开发人员提供合约代码的文件,这可以是WAST(WebAssemblyText)或WASM(WebAssemblyBinary)格式。

装配合约代码:

读取的合约文件需要进行装配,即将其转换为内部可执行的格式,以便区块链节点能够理解和执行。

存储合约代码:

装配后的合约代码将被存储在区块链上,并与指定的账号关联起来。这样,当其他用户或合约需要调用该合约时,可以通过发送交易指向该账号,并执行相应的合约操作。

通过setcode操作,合约的代码被安全地存储在区块链上,并与账号关联。这样,所有参与者都可以通过调用合约的操作来执行合约的功能,而节点可以验证合约的代码哈希值,确保合约的代码没有被篡改,从而保障合约在执行过程中的安全性和可靠性。

(三)setabi方法介绍

setabi操作用于为通过account名称标识的合约设置ABI(ApplicationBinaryInterface)。它在abi_hash_table索引中创建一个条目,使用account名称作为键,如果尚不存在,并将其值设置为ABI的哈希值。如果已存在,则更新现有account键的当前ABI哈希值。

1、setabi源码介绍

源码:

  /**
          * Set abi action sets the abi for contract identified by `account` name. Creates an entry in the abi_hash_table
          * index, with `account` name as key, if it is not already present and sets its value with the abi hash.
          * Otherwise it is updating the current abi hash value for the existing `account` key.
          *
          * @param account - the name of the account to set the abi for
          * @param abi     - the abi hash represented as a vector of characters
          */
         [[eosio::action]]
         void setabi( name account, const std::vector<char>& abi )
{
           abi_hash_table table(get_self(), get_self().value);
           auto itr = table.find( account.value );
           if( itr == table.end() ) {
              table.emplace( account, [&]( auto& row ) {
                 row.owner = account;
                 row.hash  = eosio::sha256(const_cast<char*>(abi.data()), abi.size());
              });
           } else {
              table.modify( itr, eosio::same_payer, [&]( auto& row ) {
                 row.hash = eosio::sha256(const_cast<char*>(abi.data()), abi.size());
              });
           }
        }

参数详解:

account:要部署ABI的目标账户的名称。它是一个name类型的参数,表示EOSIO中的账户名

abi:要设置的合约的ABI数据,以std::vector<char>类型的参数传入

源码详解:

通过abi_hash_table类创建一个名为table的表对象。该表用于存储账户的abi哈希值。

使用table.find()函数查找表中是否已经存在与目标账户相关的记录。

如果在表中没有找到与目标账户相关的记录(即itr==table.end()),则执行table.emplace()操作。

在table.emplace()中,通过lambda表达式将新的记录插入到表中。lambda表达式接收一个row参数,用于访问新插入的记录。在lambda表达式中,将row.owner设置为目标账户的名称,将row.hash设置为传入的ABI数据的SHA256哈希值。

如果在表中找到了与目标账户相关的记录(即itr!=table.end()),则执行table.modify()操作。

在table.modify()中,通过lambda表达式修改找到的记录。这里使用eosio::same_payer权限,确保修改操作的付款账户与原始记录的付款账户相同。在lambda表达式中,将row.hash更新为传入的ABI数据的SHA256哈希值。

ABI的实际存储方式在EOSIO中与常见的JSON文件存储方式存在较大的差异。相反,ABI被以一种被称为"原始ABI"的打包方式进行存储。

传统的开发环境中通常将ABI表示为JSON格式的文件,其中包含了合约的接口和数据结构定义。然而,在EOSIO中为了减少存储空间和提高效率,ABI被以一种更紧凑的格式进行存储。

“原始ABI”是指将ABI数据按照一定的规则进行打包和编码,以减少其存储空间。这种打包方式不同于常见的JSON文件格式,它更加紧凑,节省了存储空间,并提高了读取和解析的效率。原始ABI存储方式在EOSIO中被使用,以满足区块链中存储资源的限制和性能需求。

每个ABI都需要包含一组特定的字段,这些字段用于描述合约的不同方面,如版本信息、类型定义、结构定义、操作定义、表格定义等。这些字段的内容将被序列化为一种更节省空间的表示形式。

在EOSIO中,ABI用于定义合约的接口和数据结构。为了方便存储和传输,ABI需要被序列化为一种紧凑的二进制格式,以节省存储空间和网络带宽。

具体而言,一个典型的ABI包含以下字段:

version:ABI的版本信息,用于标识ABI的兼容性和支持的特性

types:类型定义,用于描述合约中使用的自定义类型,如结构体、枚举等

structs:结构定义,描述合约中的数据结构,包括结构体的名称、字段和类型等

actions:操作定义,描述合约中可执行的操作,包括操作的名称、参数和返回类型等

tables:表格定义,描述合约中的数据表格,包括表格的名称、字段和索引等

当执行setabi操作时,合约的ABI数据可以以两种形式之一进行提供:二进制文件或JSON文件。二进制文件是指以二进制格式存储的ABI数据文件,而JSON文件则是指以JSON格式存储的文本文件。

setabi操作需要能够处理这两种形式的ABI数据,并进行相应的转换。具体而言,它可以将二进制文件转换为JSON格式的ABI数据,或将JSON格式的ABI数据转换为二进制格式,即序列化和反序列化的过程。这样,合约开发人员可以选择以更适合他们的方式提供ABI数据,并将其转换为适合在区块链上存储和使用的形式。

END

Fintoch系统开发智能合约部署dapp开发技术

Fintoch系统开发智能合约部署dapp开发技术

合约一般是法律上认可的、会被法庭强制执行的平等主体间的协议。就是市场交易双方或多方之间,基于各自的利益要求所达成的一种协议。可以是口头或书面形式。它陈述了遵守或不遵守协议的规则和后果。它是正式的或非正式的系统開发180-383I-97Z4

 

class Mat

{

public:

int m = 1, n = 1; //行数和列数

double mat[N][N] = { 0 };  //矩阵开始的元素

 

Mat() {}

Mat(int mm, int nn)

{

m = mm; n = nn;

}

 

void create();//创建矩阵

void Print();//输出矩阵

bool add(const Mat a, const Mat b);//加法

bool sub(const Mat a, const Mat b);//减法

bool mul(const Mat a, const Mat b);//乘法

};

 

 为什么我们需要合约?

 合约通过确保协议条款的明确性,以及商定协议将会发生的结果;如果不是,则将受到预期的处罚,以此保护参与合约各方的利益。因此,合约,将提供交易的安全性,最小化冲突和争议,并保护各当事方的财产等。

今天关于web3.js_1.x.x--API(二)/合约部署与事件调用如何部署合约代码的介绍到此结束,谢谢您的阅读,有关asp.net-web-api – Web API / MVC 6中的安全JSON Web令牌、defi质押lp挖矿dapp系统开发合约部署详情、eosio.system智能合约介绍(四)合约部署介绍、Fintoch系统开发智能合约部署dapp开发技术等更多相关知识的信息可以在本站进行查询。

本文标签: