Context
У меня установлена сеть кворума по примеру 7узлов . В узле 1 я развернул смарт-контракт в частном порядке, поместив открытый ключ этого "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo="
в закрытый вид.
Моя цель - перейти к этому умному контракту, выполнить одну из его функций. Будучи частным договором, перевод должен быть подписан.
Все это с сервера nodejs.
Код
Смарт-контракт заключается в следующем:
pragma solidity ^0.4.19;
contract SimpleStorage {
uint storedData;
uint secondData;
uint TData;
function set(uint x) external {
storedData = x;
}
function setSecond(uint x) external {
secondData = x;
}
function setT(uint x) external {
TData = x;
}
function get() external view returns (uint retVal) {
return storedData;
}
function getSecond() external view returns (uint retVal) {
return secondData;
}
function getT() external view returns (uint retVal) {
return TData;
}
}
Код в nodejs следующий:
const Web3 = require('web3');
const EthereumTx = require('ethereumjs-tx');
const contract = require('truffle-contract');
const simpleStorageInterface = require("./contracts/SimpleStorage.json");
var web3 = new Web3(
new Web3.providers.HttpProvider('http://172.10.4.159:22000')
);
var generalInfo = {
contractAddress: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
account: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
keystore: {"address":"ed9d02e382b34818e88b88a309c7fe71e65f419d","crypto":{"cipher":"aes-128-ctr","ciphertext":"4e77046ba3f699e744acb4a89c36a3ea1158a1bd90a076d36675f4c883864377","cipherparams":{"iv":"a8932af2a3c0225ee8e872bc0e462c11"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"8ca49552b3e92f79c51f2cd3d38dfc723412c212e702bd337a3724e8937aff0f"},"mac":"6d1354fef5aa0418389b1a5d1f5ee0050d7273292a1171c51fd02f9ecff55264"},"id":"a65d1ac3-db7e-445d-a1cc-b6c5eeaa05e0","version":3},
bytecode: "0x608060405234801561001057600080fd5b506101ec806100206000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631b03316f1461007d57806322554f34146100a857806360fe47b1146100d35780636d4ce63c14610100578063b698c1291461012b578063f5f3194114610158575b600080fd5b34801561008957600080fd5b50610092610185565b6040518082815260200191505060405180910390f35b3480156100b457600080fd5b506100bd61018f565b6040518082815260200191505060405180910390f35b3480156100df57600080fd5b506100fe60048036038101908080359060200190929190505050610199565b005b34801561010c57600080fd5b506101156101a3565b6040518082815260200191505060405180910390f35b34801561013757600080fd5b50610156600480360381019080803590602001909291905050506101ac565b005b34801561016457600080fd5b50610183600480360381019080803590602001909291905050506101b6565b005b6000600154905090565b6000600254905090565b8060008190555050565b60008054905090565b8060018190555050565b80600281905550505600a165627a7a723058209cc3ec1ccb2383d74522ba2e5974347862883f4c4aa826bb69e6e1cfcc5bdd110029",
interface: [{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"setSecond","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"setT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSecond","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getT","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}],
privateFor: "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo="
}
web3.eth.getAccounts().then(async (_result) => {
// Set web3 default account
web3.eth.defaultAccount = _result[0];
// Get truffle-contract
let myContract = contract(simpleStorageInterface);
// Set provider
myContract.setProvider(web3.currentProvider);
if (typeof myContract.currentProvider.sendAsync !== "function") {
myContract.currentProvider.sendAsync = function() {
return myContract.currentProvider.send.apply(
myContract.currentProvider, arguments
);
};
}
// Instanciate the contract
var contractInstance = new web3.eth.Contract(simpleStorageInterface.abi, generalInfo.contractAddress);
// Function data
let encodedABI = contractInstance.methods.set(123).encodeABI();
let nonce = await web3.eth.getTransactionCount(web3.eth.defaultAccount);
// Transaction
let tx = {
nonce: web3.utils.toHex(nonce),
from: generalInfo.account,
to: generalInfo.contractAddress,
gas: 2000000,
gasPrice: 0,
data: encodedABI,
privateFor: [generalInfo.privateFor]
}
let decrypt = web3.eth.accounts.decrypt(generalInfo.keystore, "");
// Remove 0x from private key
var privateKey = decryptKey.privateKey.substring(2);
var bufferPK = new Buffer(privateK, 'hex');
// Generate transaction using "ethereumjs-tx"
var transaction = new EthereumTx(tx);
// Sign transaction
transaction.sign(bufferPK);
// Send signed transaction
web3.eth.sendSignedTransaction("0x" + transaction.serialize().toString('hex'), (_err, _res) => {
if(_err){
console.error("ERROR: ", _err);
} else {
console.log("Success: ", _res);
}
}).on('confirmation', (confirmationNumber, receipt) => {
console.log('=> confirmation: ' + confirmationNumber);
})
.on('transactionHash', hash => {
console.log('=> hash');
console.log(hash);
})
.on('receipt', receipt => {
console.log('=> reciept');
console.log(receipt);
})
.on('error', console.error);
});
Вопрос и проблема
Транзакция выполнена успешно, но новое значение «123» в смарт-контракте не изменилось. Только если я разблокирую аккаунт до того, как транзакция await web3.eth.personal.unlockAccount (account, "")
заработает, но я не хочу блокировать и разблокировать аккаунт по соображениям безопасности.
Правильный перевод будет следующим:
{
blockHash: "0xe5a2df3f592392c71f9995d697721c046f60c81d2988418b0c7b929cb17a0cee",
blockNumber: 2190,
from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
gas: 90000,
gasPrice: 0,
hash: "0x24df9e01d9fdb7acc7a2842dcdd1d93a37e7be7885ef469a262d8a690f7143f3",
input: "0xb0101ef545cf42bb490bca4fac873ea06d989abf1fbdc89f7dfd09014c085f163c371efa5acac2b43c9dec5cb20bd11e853069a99f4bcb938d6fdcd6f2918333",
nonce: 31,
r: "0x9851006a766b4bd75051cdba9c06b6d251125d68894983eee3a4c1a53a03d77a",
s: "0x1696039cedf14a82147c858bc17896664c9c74bda313307dbf9386b7d6893938",
to: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
transactionIndex: 0,
v: "0x25",
value: 0
}
Шахта выглядит так:
{
blockHash: "0x6a2aacceabe984b2c368fa9ca7c245065924dd6d88e30f81311e2a5a7e2aeab8",
blockNumber: 2119,
from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
gas: 2000000,
gasPrice: 0,
hash: "0x4a918c1641478c1f229e7cdfff93669a6e08b37555eafe871fc3b05717cbcb79",
input: "0x60fe47b1000000000000000000000000000000000000000000000000000000000000007b",
nonce: 30,
r: "0xac64a34de4bf0c2d3f1d8da6af3d38ee12be38846f744004eeef460ad94b528e",
s: "0x10e642925665877c4e2571a2f835af68c025417574462ffc4864e6128e4a4deb",
to: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
transactionIndex: 0,
v: "0x1c",
value: 0
}
Разница заключается в свойстве "v", значение, которое фиксируется в моем переводе, неверно, оно должно быть 0x25 или 0x26, чтобы идентифицировать их как частные переводы. Я не понимаю, почему эти значения плохо устанавливаются, помогите, пожалуйста.