如何使用Ganache开发、测试和部署智能合约

5,584 阅读6分钟

开发、测试和部署智能合约是区块链开发者的一项重要工作,本教程将告诉你如何开始使用智能合约。

在我们进入之前,了解加密货币和区块链的基本概念很重要。如果你对加密货币不熟悉,我建议你看这个简短的视频

什么是智能合约?

智能合约是存储在区块链上的不可变的程序。它们根据预定条件的满足,自动执行交易,它们被广泛用于以去中心化的方式执行协议,没有中间人。

智能合约有特定的结果,由不可变的代码管理,所以合约的参与者可以对合约的执行有信心。没有第三方参与,没有时间损失--当条件得到满足时,协议立即执行。

智能合约可以被部署在区块链上使用。以太坊支持用Solidity编程语言编写的智能合约。

前提条件

本教程使用JavaScript和Solidity来开发、测试和部署Ethereum区块链上的智能合约。

所以,你需要有JavaScript、Node.js和Solidity的基本知识。

Solidity与JavaScript相似,所以这些概念相当容易掌握。

设置项目

本教程将是相当简单的。请查看这个GitHub repo,看看本教程中的代码。

我们将使用这些工具来开发和测试智能合约。

  • Ganache
  • Truffle(用npm i truffle -g 安装)
  • 用于测试的JavaScript
  • 用于智能合约代码的Solidity

初始化Truffle

Truffle为您提供了开发和测试智能合约的所有必要工具。你可以用truffle init 来初始化一个Truffle项目。

$ truffle init

 Preparing to download
 Downloading
 Cleaning up temporary files
 Setting up box

Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

$ ~

这应该创建一个新的项目,有三个文件夹(/contracts,/migrations, 和/tests )和一个配置文件,truffle-config.js

创建一个Ganache以太坊区块链实例

在你下载Ganache后,快速启动一个区块链实例。你应该看到像这样的屏幕。

Ganache Dashboard

检查RPC服务器配置中的端口。,通常是7545 。现在,在truffle-config.js 中做如下修改,并填写正确的端口号。

module.exports = {
  networks: {
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 7545,            // Standard Ethereum port (default: none)
     network_id: "*"        // Any network (default: none)
    }
  }
}

现在,运行truffle migrate 。如果它没有抛出任何错误,你就可以开始了。

编写智能合约

契约将被存储在/contracts 文件夹下。你会发现这里已经存在migrations.sol

在该目录下创建一个新的文件,名为TruffleTutorial.sol

pragma solidity >=0.4.22 <0.9.0;

contract TruffleTutorial {
  address public owner = msg.sender;
  string public message;

  // this function runs when the contract is deployed
  constructor() public {
    // set initial message
    message = "Hello World!";
  }

  modifier ownerOnly() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  // function that only contract owner can run, to set a new message
  function setMessage(string memory _message) 
    public 
    ownerOnly 
    returns(string memory) 
  {
    // message must not be empty
    require(bytes(_message).length > 0);

    // set new message
    message = _message;
    return message;
  }
}

注意,这就是名为TruffleTutorial 的智能合约。你可以查看代码中的注释,了解每个函数和每行代码的作用,但我将在这里解释要点。

这个智能合约存储了一条信息,并且只允许智能合约的所有者改变这条信息。该合约还允许区块链上的每个人都能阅读这条消息。当合约首次部署时,智能合约中存储在区块链上的消息将是,"Hello World!"。

你也可以在remix.ethereum.org上快速测试智能合约

将智能合约部署到Ganache Ethereum本地测试网络上

现在,让我们把这个智能合约部署到Ganache本地测试网络启动的区块链实例。

如果你以前使用过MySQL或Postgres等数据库,我想你对迁移很熟悉。

/migrations 文件夹中,你会看到初始迁移。你必须为这个新的智能合约创建一个新的迁移文件。

创建2_TruffleTutorial_migration.js

// Help Truffle find `TruffleTutorial.sol` in the `/contracts` directory
const TruffleTutorial = artifacts.require("TruffleTutorial");

module.exports = function(deployer) {
  // Command Truffle to deploy the Smart Contract
  deployer.deploy(TruffleTutorial);
};

你可能想知道artifactsdeployer 的功能是什么。它们是由Truffle负责的。当你运行truffle migrate ,它查看/migrations 目录,并将所有链接的智能合约部署到区块链上,就像迁移文件所告诉它们的那样。

当你用这段代码创建文件时,只需运行truffle migrate --reset ,它将把智能合约部署到本地测试网络。它还会建立以太坊虚拟机能够理解的ABI和字节码文件。

与已部署的智能合约进行互动

现在你的智能合约已经在区块链上了,你如何与它互动?你如何检索信息,以及如何设置它?Truffle控制台正是让我们这样做的。

与智能合约互动的更简单的GUI方法是通过remix.ethereum.org/。

在终端中,编码truffle console ,这将启动一个控制台,使你能够与智能合约互动。

$ truffle console
truffle(development)> const truffleTutorial = await TruffleTutorial.deployed()
truffle(development)> const address = await truffleTutorial.address
truffle(development)> address
'0x46C00D73bF785000B3c3F93569E84415AB2381f2'

尝试所有这些行,看看你是否得到了地址。如果你做到了,智能合约就成功部署了,你的项目可以和它对话。

现在试着获取存储在智能合约上的信息。

truffle(development)> const message = await truffleTutorial.message()
truffle(development)> message
'Hello World!'

你现在可以读取存储在智能合约上的值了

让我们试着设置一个新的消息。

truffle(development)> await truffleTutorial.setMessage('Hi there!')
truffle(development)> await truffleTutorial.message()
'Hi there!'

好了,你做到了!智能合约成功了智能合约起作用了!

虽然,我们是手动测试的。理想情况下,你会希望设置自动测试,检查这一切是否完美运行。

测试智能合约

你将在/test 文件夹中编写测试。在那里创建一个名为TruffleTutorial.js 的新文件。

const { assert } = require("chai")

const TruffleTutorial = artifacts.require("./TruffleTutorial.sol")

require("chai")
  .use(require("chai-as-promised"))
  .should()

contract('TruffleTutorial', ([contractOwner, secondAddress, thirdAddress]) => {
  let truffleTutorial

  // this would attach the deployed smart contract and its methods 
  // to the `truffleTutorial` variable before all other tests are run
  before(async () => {
    truffleTutorial = await TruffleTutorial.deployed()
  })

  // check if deployment goes smooth
  describe('deployment', () => {
    // check if the smart contract is deployed 
    // by checking the address of the smart contract
    it('deploys successfully', async () => {
      const address = await truffleTutorial.address

      assert.notEqual(address, '')
      assert.notEqual(address, undefined)
      assert.notEqual(address, null)
      assert.notEqual(address, 0x0)
    })

    // check if the message is stored on deployment as expected
    it('has a message', async () => {
      const message = await truffleTutorial.message()
      assert.equal(message, 'Hello World!')
    })
  })

  describe('message', () => {
    // check if owner can set new message, check if setMessage works
    it('contract owner sets a message', async () => {
      // set new message
      await truffleTutorial.setMessage('Hi there!', { from: contractOwner }) 
      // `from` helps us identify by any address in the test

      // check new message
      const message = await truffleTutorial.message()
      assert.equal(message, 'Hi there!')
    })

    // make sure only owner can setMessage and no one else
    it('address that is not the owner fails to set a message', async () => {
      await truffleTutorial.setMessage('Hi there!', { from: secondAddress })
        .should.be.rejected
      // this tells Chai that the test should pass if the setMessage function fails.

      await truffleTutorial.setMessage('Hi there!', { from: thirdAddress })
        .should.be.rejected
    })
  })
})

在这里,我们正在使用Chai测试框架来断言数值,看看它们是否成立。如果你看到这段代码,你会意识到它与你在Truffle控制台中尝试的类似,只是这次你将这些代码行与Chai测试框架配对。

assert.equal 需要两个参数,如果它们匹配,测试就通过,否则就失败。

现在,运行truffle test 。你应该看到所有的测试都通过了。

$ truffle test
Using network 'development'.

  Contract: TruffleTutorial
    deployment
      ✓ deploys successfully
      ✓ has a message (236ms)
    message
      ✓ contract owner sets a message (165ms)
      ✓ address that is not the owner fails to set a message (250ms)

  4 passing (735ms)

你现在已经使用Truffle和Ganache开发、测试并部署了智能合约。

奖励:将智能合约部署到Ethereum主网上

请注意,在Ethereum Mainnet上部署将需要你支付一些气体费用。另外,每次你在区块链上写东西(例如,在执行setMessage 函数时),都会花费你的汽油费,但阅读智能合约仍然是免费的。

首先,安装Metamask浏览器扩展。现在,访问remix.ethereum.org。

在这里,创建或编辑现有的项目--在/contracts 文件夹中创建TruffleTutorial.sol ,并在那里粘贴所有的智能合约代码。

在侧边栏中,你应该看到一个选项,可以切换侧边栏中的SOLIDITY COMPILER窗格。点击它并编译solidity智能合约代码。它应该创建ABI和字节码文件。

编译完成后,从侧边栏打开DEPLOY & RUN TRANSACTIONS窗格。您可以尝试在Remix Ethereum Test JavaScript VM网络上部署智能合约。您也可以在同一窗格中使用Remix工具本身进行手动测试。

现在是时候部署到主网了。首先,确保你的Metamask钱包里有一些以太坊余额,以便你可以支付汽油费。我通常在我的coinbase钱包里放50美元左右的以太坊,然后把以太坊转到Metamask钱包里。

DEPLOY & RUN TRANSACTIONS窗格中,将 "环境 "从JavaScript VM 设置为Injected Web3 。当你这样做时,你将把你的Metamask钱包连接到主网。最后,点击部署。你将不得不与Metamask签署一个交易,但一旦完成,你的TruffleTutorial 智能合约将被部署!

确保你在部署后检查智能合约的地址,以便其他客户想要与你的智能合约对话时可以使用该地址。

总结

Web3正在蓬勃发展,这个空间是新的和令人兴奋的。智能合约是大多数Dapps(去中心化应用程序)的后端,如果你想成为区块链开发者,学习如何开发、测试和部署它们将是非常有用的。

The postHow to develop, test, and deploy smart contracts using Ganacheappeared first onLogRocket Blog.