Полное руководство по Solidity
Смарт-контракты неизменяемы по умолчанию, то есть вы не можете изменить код смарт-контракта при их развертывании, если вы повторно развернете смарт-контракт, он сгенерирует новый адрес, и вы потеряете свои прежние данные смарт-контрактов.
Это совершенно нормально, если вы не собираетесь менять код своего смарт-контракта в любой момент.
Но если вы когда-нибудь в будущем измените код своего смарт-контракта, вам нужно подумать об эффективном способе переноса вашего смарт-контракта без потери данных и адреса контракта.
Существуют ручные способы переноса данных смарт-контрактов и принуждения пользователей к использованию вновь сгенерированного адреса путем отключения старого, но это трудоемкая задача.
В этой статье мы узнаем, как писать обновляемые смарт-контракты, используя обновляемые библиотеки OpenZeppelin и Truffle.
Давайте возьмем контракт Kickstarter в качестве варианта использования. Kickstarter — это платформа, которая позволяет пользователям создавать кампании для определенной цели, а другие пользователи могут вносить свой вклад в кампанию.
Предпосылки
- Справедливое понимание Solidity и Truffle
- Nodejs и нпм
ganache-cli
или десктопное приложение Ганаш- Трюфель
Если у вас не установлены Node.js или npm, вам придется установить их, также установить ganache-cli
или рабочий стол.
Я предпочту установить truffle глобально с помощью npm install -g truffle
, но если вы решите установить его локально, все будет в порядке.
После установки создайте каталог проекта с именем по вашему выбору, откройте каталог в терминале и выполните эту команду:
truffle init
truffle init
создаст для вас контракты и каталог миграции, а также файл truffle-config.js
. Затем обновите truffle-config
:
Если вы хотите использовать сеть ropsten
, создайте файл .env
и добавьте сетевые переменные ropsten
.
После обновления файла конфигурации truffle установите необходимые зависимости npm:
npm install @openzeppelin/contracts-upgradeable @openzeppelin/truffle-upgrades @truffle/hdwallet-provider dotenv
Затем в папке с контрактами создайте два файла Kickstart.sol
и KickstartFactory.sol
.
Migration.sol
был создан при запуске truffle init
. Обновите контракт Migration
нижеследующим. Он заимствован из примера, упомянутого в официальной документации трюфеля.
Вставьте следующий код в файл Kickstart.sol
:
Если вы заметили, я использовал геттеры и сеттеры для доступа и изменения переменных контракта.
Это спецификация OpenZepplin
для изменяемой изменяемой переменной смарт-контракта. Также нет функции конструктора, вместо этого использовалась инициализированная функция.
Подробнее об инициализаторах контрактов можно прочитать здесь.
Вставьте следующий код в файл KickstartFactory.sol
:
В папке migrations
:
// 1_initial_migration.js const Migrations = artifacts.require("Migrations"); module.exports = function (deployer) { deployer.deploy(Migrations); };
Truffle создаст эту первую начальную миграцию (1_initial_migration.js
) для вас, когда вы запустите команду truffle init
.
Создайте новый файл миграции в каталоге миграции 2_deploy_contracts.js
:
// 2_deploy_contracts.js const { deployProxy } = require('@openzeppelin/truffle-upgrades'); const Kickstart = artifacts.require("Kickstart");const KickstartFactory = artifacts.require("KickstartFactory"); /** Deploy contract using openzeppelin deployProxy, which will create a proxy address for you */ module.exports = async (deployer) => { const factory = await deployProxy(KickstartFactory, { deployer }); const kickstart = await deployProxy(Kickstart, [100, '0x0000000000000000000000000000000000000000'], { deployer }); };
После вставки приведенного выше кода выполните следующие команды:
truffle compile truffle migrate // Or truffle deploy // truffle deploy is an alias for truffle mograte
После успешной миграции с помощью truffle migrate
запустите:
truffle console
В консоли контракта выполните следующие команды:
// This will create KicstartFactory contract instance let factory = await KickstartFactory.deployed() // Create a new kickstart campaign factory.createCampaign(100) // Get the created campaign factory.getDeployedCampaigns() // Copy the address in the campaign list // Create a kickstart instance by running this command let kickstart = await Kickstart.deployed('0x11924C6967680124814fe7bFE0EB4a352CEB9Ef6') // Replace the address with the address copied from the campaign list
Чтобы обновить контракт KicstartFactory
и добавить новый function get DeployedCampaignsLength()
, создайте новый файл в каталоге contracts
и назовите его KickstartFactoryV2.sol
.
Эта функция получит общее количество развернутых кампаний:
Создайте новый файл миграции 3_upgrade_contracts.js
в каталоге migration
, вставьте в файл следующий код.
// 3_upgrade_contracts.js const { upgradeProxy } = require('@openzeppelin/truffle-upgrades'); const KickstartFactory = artifacts.require("KickstartFactory"); const KickstartFactoryV2 = artifacts.require("KickstartFactoryV2"); module.exports = async (deployer) => { const existing = await KickstartFactory.deployed(); console.log('Existing Address ===', existing.address); const instance = await upgradeProxy( existing.address, KickstartFactoryV2, { deployer }); console.log("Upgraded Address ===", instance.address); };
Если вы заметили, на этот раз мы не развернули контракт KickstartFactory
.
Вместо этого мы получили экземпляр уже развернутой версии и передали адрес новой версии, используя existing.address
в качестве первого параметра для функции updateProxy
После вставки предыдущего кода выполните следующие команды:
truffle compile truffle migrate // Or truffle deploy
Примечания
При создании обновляемых контрактов с помощью truffle никогда не пытайтесь перенести свой контракт с помощью reset flag (truffle migrate — reset)
, развертывание со сбросом удалит все ваши существующие состояния и данные контрактов, запустите новую миграцию, которая также изменит адрес ваших контрактов. .
Если вы хотите сбросить свои контракты в среде разработки, вы можете это сделать, но не рекомендуется использовать reset
для контракта в рабочей среде.
Надеюсь, вы узнали, как создать обновляемый смарт-контракт Solidity с помощью трюфеля и openzeppelin
обновляемых библиотек. Вы также можете создавать обновляемые смарт-контракты с openzeppelin
и hardhat
.
Клонируйте полный код на GitHub, также ознакомьтесь с моим Проектом Solidity kickstart GitHub Project, который представляет собой не обновляемую версию этого проекта с тестовыми примерами, а также имеет интерфейс для взаимодействия со смарт-контрактом ABIS.
Спасибо.