У меня есть существующий проект node/graphql/mongodb/react/redux, который находится в стадии бета-тестирования, и я хотел бы интегрировать смарт-контракты Ethereum, чтобы иметь возможность сохранять информацию о транзакциях в цепочке блоков. Это возможно? Если да, то как мне это сделать?
У меня уже есть практические знания Solidity и Truffle, я создал пару примеров проектов и развернул их в частной сети.
Может лучше начать с нуля?
Самый простой способ управлять приложением JavaScript, взаимодействующим с блокчейном, — это использовать среду разработки и инструмент развертывания, например Truffle .
Truffle позаботится о том, чтобы дать вам возможность запускать тесты и миграции, а также управлять определениями ваших контрактов, включая адреса, на которые они развернуты в каждой сети. Он также предоставляет хорошие учебные пособия , которые помогут вам научиться писать приложения, взаимодействующие с блокчейном.
В наиболее распространенных примерах использования Truffle будет использоваться собственная библиотека сборки для всего вашего приложения, но если у вас уже есть существующее приложение React, у вас, вероятно, уже есть собственный процесс сборки с использованием browserify
или webpack
какого-либо другого инструмента. Теоретически это можно легко интегрировать с truffle
, но может быть проще, привыкнув к тому, как работает Truffle, просто поместить его в подкаталог вашего собственного проекта и напрямую ссылаться на его библиотеки и контрактные json-файлы, которые он создает.
См. этот проект для примера. Исходный truffle
каталог содержит контракты, миграции и тесты контрактов, и запуск truffle migrate
из этого каталога приведет к развертыванию контрактов в блокчейне и сохранению их определений в своем build
каталоге. Файл truffle.js
определяет сеть, в которой он будет развернут, но не (в отличие от большинства учебных пособий Truffle) процесс сборки HTML и JavaScript веб-приложения, поскольку он обрабатывается исходной системой приложения, как определено в его файле package.json
. Основной внешний интерфейс JavaScript загружает определения контрактов, сгенерированные трюфелем, и взаимодействует с ними с помощью инструментов, найденных в truffle-contract
библиотеке.
Пример ниже не совсем подходит для сохранения информации о транзакциях в блокчейне. Но для вызова передаточной функции, написанной в смарт-контракте из кода nodejs. Надеюсь, это поможет.
1> Контракт:
contract SmartToken {
//store mapping of address and tokens (like a hashmap)
mapping(address => uint) tokens;
event OnamountChanged(address indexed _fromAddress, uint amount);
//transfer amount from one account to another account
function transfer(address fromAddress, address toAddress, uint amount) returns (bool success) {
//Cannot transfer to same account
if (fromAddress == toAddress) {
return false;
}
//change balance of accounts
if ((tokens[fromAddress] - amount) < 0) {
//Transfer entire amount
token[toAddress] += tokens[fromAddress];
tokens[fromAddress] = 0;
} else {
token[toAddress] += amount;
tokens[fromAddress] -= amount;
}
OnamountChanged(fromAddress, tokens[fromAddress]);
return true;
}
}
2> узлы:
exports.transferTokens = function (transferData, next) {
var rfr = require('rfr');
//Copy abi into a json file and put it somewhere within nodejs app folder somewhere
var abiJson = rfr('/app/account/queries/SmartToken.json');
//Copy your contract address here
var contAddr = "Your Contract Address";
var bcHelper = rfr('/app/utils/bcHelper.js');
//Get connection to your blockchain - see helper code in #3 below
var bcConn = bcHelper.myBcConnection();
//Reference to ABI JSON
var contractAbi = bcConn.eth.contract(abiJson);
//Reference to contract address
var contractRef = contractAbi.at(contAddr);
//fromAddress, toAddress, password and amount are passed from my UI in json format
var fromAddress = transferData.fromAddress;
var toAddress = transferData.toAddress;
var password = transferData.password; //password of fromAccount
var transferAmount = transferData.amount;
//Default account is required for smart contract write
bcConn.eth.defaultAccount = bcConn.eth.coinbase;
//unlockAccount so that it is open to transfer required tokens
bcConn.personal.unlockAccount (fromAddress, password, 15000, function(err, result) {
if (err) {
return next(err, null);
}
//invoke transfer function on smart contract in #1
contractRef.transfer(fromAddress, toAddress, transferAmount, function (err, result) {
if (err) return next(err, null);
return next(null, result);
});
});
};
3> вспомогательный файл: bcHelper.js
var Web3 = require('web3');
var myBcInstance;
exports.myBcConnection = function() {
if (myBcInstance) {
return myBcInstance;
} else {
//Connect to web3 instance
myBcInstance = new Web3(new Web3.providers.HttpProvider('http://localhost:8042');
return myBcInstance;
}
};
Джейсон Кокран