ααΌααα»αααΆααααααααα·ααααα·ααΆαα―ααα αα·αααΆααΆααα α αΎαααΆαααααΈααααΎααααΆααααΆαα·αααααααααΆα αααΎαα
αα αααα»αα’αααααααα ααΎαααΉααα·αα·αααααΎαααααΆααΈαααΌαααααααα½α - ααΆαααΆαααααααΆααααααΆααααααΈααΆαααΆαα ααα αΆααααΆαααααΆαααααΎα αα·αααα αΆααααααΆαα ααΎααααΈαααααααααααΆαααααΈαα’αααΈααΈαα»ααα ααΆαααααααΆααα
ααΌαβαααβααααΎβαααα»αβααΆαβααααααβαααβααΊβαα
βαααα»α
α’αααααααααααααααα
- ααΆααααααΎααα·α αα αααααΆααααΆααα;
- ααΆαααΆαααααααΆααααααΆαααΌααα»ααααααααΎ
ααΆααΊα ; - ααΌααα»α ααααα·ααααα·ααΆαααΆααΆααα;
- ααααα·ααααα·ααΆαα―αααααααΌααα»αα
ααΎααααΈαααα αΆα ααΎαααααΎααααΆααΈαααΌαααααΆαααααα½ααα·αα·αααααΈαα»ααα ααΆααα αααα»αααααΆαααααααααΆαα·ααααααααΆαααΌααα»ααα αααα»αα’ααΈαααΊαααααα’αααΈα (IoT)α
ααα·αα
αααα»αβα αα»αβααααΆααβαα½αβαααα»αβαα½αβαα½αβααααΆβαααα»αβαααα»αβα αα»αβαα½αβααΎααααΈβαααααΆβαα»αβααααααΆαβαα½αβααααΆ αα·αβααααΎβααααΎαβααΆαβαααβαααααβαααααααα·βαα βααΎ blockchainα αααααΆαααααα αΆααα αααα»αα αα»αααΆααααααα α α·αααααααΎααΌααα»αα αα αααα»αα’αααααααα ααΎαααΉααααααΆααα’αααΈααααΆααΈαααΌααΈαα ααααα·ααααα·ααΆαααΆααΆααα αα·αααααα·ααααα·ααΆαα―αααα
ααααα·ααααα·ααΆαααααΌαααΆααααααΎαα‘αΎααααα’αααα αΌααα½αααααααααααΆααΎααααΈααααΎα’ααααααααααΆαα½αααααααααααααα½αααααΆαααααα·αααα·α ααααα·ααααα·ααΆαααΈαα½ααααΆαααααααΆααα·α αα αααααΆ α¬α α αα»αααΆααα½ααα αααα»ααα·α αα αααααΆ ααΎααααΈαααα»ααα·αααααααα αααα»ααααααΆαα αααααααΆαααΆαααααααααΌαααΆαα αααααα ααΆααααααΆααααΆααα’αααα ααΎαααααΆαα
ααααα·ααααα·ααΆαααΆααΆαααααΊα’αΆα ααααΆααααααΆααααΎααααα’αααα αΌααα½ααααααααααααααα ααααα·ααααα·ααΆαα―ααααααααααααααΆααααααΆααααααΆαα α αΎαααΆααααααΆααααα’αααα αΌααα½ααααααΆααα·αααα·ααααΎααΌα ααααααα»αααααα
αααααΆααααααΆααΈαααΌααΆααααΈα ααΎαααααΎαα·α αα αααααΆααΌα ααααΆαααααΆααααΆαα αααΆααααΆααα
αα·α αα αααααΆααααΆααα
ααΆαααααααααααΊααΆαα·α
αα
αααααΆααααΆαααααΆαααααα½ααααααααΌαααΆααααααΎαα‘αΎααααααΆααααααΆααΈαααΌααααααΎαα ααΆααΆαα’αααααΆααΆααα temperature
αααα’αΆα
ααααΆααααααΌαααΆααααααααΎ set
αα·αααα½αααααα·ααΈααΆααααα get
.
pragma solidity ^0.4.25;
contract TemperatureMonitor {
int8 public temperature;
function set(int8 temp) public {
temperature = temp;
}
function get() view public returns (int8) {
return temperature;
}
}
ααΎααααΈα±αααα·α
αα
αααααΆααααΎααΆαααΆαα½α formatContract
ααΆααααααα
ααααααα·α
αα
αααααΆαααααααΎ
function formatContract() {
const path = './contracts/temperatureMonitor.sol';
const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}
αα·α αα αααααΆαααααΆααααα ααααΎααα ααΌα αααα
// interface
[
{
constant: true,
inputs: [],
name: βgetβ,
outputs: [Array],
payable: false,
stateMutability: βviewβ,
type: βfunctionβ
},
{
constant: true,
inputs: [],
name: βtemperatureβ,
outputs: [Array],
payable: false,
stateMutability: βviewβ,
type: βfunctionβ
},
{
constant: false,
inputs: [Array],
name: βsetβ,
outputs: [],
payable: false,
stateMutability: βnonpayableβ,
type: βfunctionβ
}
]
// bytecode
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029
α₯α‘αΌαααααα·α αα αααααΆαα½α ααΆαα ααΎαααΉααααααΆααααααΆα αα·ααααααΆααα·α αα αααααΆα
ααΆαααΆαααααααΆαααααΆαα
ααΆαααΆαααααααΆαααααΆααα’αΆα
ααααΎαααααΆααααααααααααΆαα α αΎαααααΎαααΆααααα’αΆα
ααααΌαααΆααααα½ααααααΆαααααΎααααΆααααααΆαααα
ααΆαααααααααααΊααΆααααΎαααΆααααααΆααααΆαααααααΆααααααΆα Quorum ααΆαα½αααΉα Raft consensus αα·αααααΆααααΈα
ααΆααααΌα α αΌαααΎααααααΎααααααααα½α α αΎαα α ααΆααΆ ααααααααΌααα»αα
ααααααααΎααααααΆα Quorum ααΆαα½α Raft consensus αα ααΎ Google Cloud Platformα
αααααααααααααΆααααΈαααααα ααααΆαααααααΆααααααΎααα½α α αΎαααΆαααααΆαααΎαα
ααααΆααααααααα»αααααΎαααΆαααΈα
ααααααααααΆαααα’α·αααααααααΆαααααα αΆαα ααα»α αααα αα RPC ααααΆααΆαααααα
αααααΆαααααΌαααΆαααΆαααααααΆαα α₯α‘αΌαααα α
αΌαααΎαααΆαααααααΆααα·α
αα
αααααΆααααΆααα αα·αααααΎααααα·ααααα·ααΆααααααααΎ
ααααα·ααααα·ααΆαααΆααΆααα
ααα·αα
ααΈαα»ααα ααΆααααα»αααααΆααααΆαααΆααααααΆααααααΆαααααα»αααΆαααΆαααααααααΆαα αααΆα ααΆαα·ααααααααΆααααα·ααααααααΆααααααααααΆαα»ααα ααΈαα»ααα ααΆαααααΌαααα
αααα’αα»ααααΆαα±αααααα»αα αα»αα αααααααααΈαα»ααα ααΆαααΆααααα ααααΈααΆααααΌαα·ααΆααααααααααα½ααααααα»ααααααααΆααΆααααααα α αΎααααααααΆααΆαα αααα»αααααα αααααααΆααααα·αα’αΆα ααααΆααααααΌαααΆα α’αααα αΌααα½ααααααΆαααΆαααααααααΆαα αααΆα αα·ααααααααΆα
ααΎαβααΉαβα’αα»ααααβαα·α αα ααΆαβααΈβαααβαααα αΆαβαααα»αβααααΆααααΆαα
-
ααΎαααΉαααΆαααααααΆααα·α αα αααααΆααΆαααα ααααΆαα 1:
const contractAddress = await deployContract(raft1Node); console.log(`Contract address after deployment: ${contractAddress}`);
-
αααααααΈαα»ααα ααΆαααΆαααα ααααΆαα 2 ααα 3 ααΊαααα:
const status = await setTemperature(raft2Node, contractAddress, 3); console.log(`Transaction status: ${status}`);
-
ααααΆαα 3 ααΉαααα½αααΆαααααααΆαααΈαα·α αα αααααΆααααΆαααα αα·α αα αααααΆααΉααααα‘ααααααα 3 ααΊααααα
const temp = await getTemperature(raft3Node, contractAddress); console.log(βRetrieved contract Temperatureβ, temp);
αααααΆαα ααΎαααΉααα·αα·αααααΎαααααααααα·ααααα·ααααα·ααααα·ααΆαααΆααΆααααα ααΎαααααΆαααΌααα»ααααααααΎ
ααα ααααα 3.js .
ααΎαα αΆααααααΎαα§ααΆα αααααΆαααα RPC αααααΆααααααΆααααΈα
const raft1Node = new Web3(
new Web3.providers.HttpProvider(process.env.RPC1), null, {
transactionConfirmationBlocks: 1,
},
);
const raft2Node = new Web3(
new Web3.providers.HttpProvider(process.env.RPC2), null, {
transactionConfirmationBlocks: 1,
},
);
const raft3Node = new Web3(
new Web3.providers.HttpProvider(process.env.RPC3), null, {
transactionConfirmationBlocks: 1,
},
);
αααααΆαααααααΆααα·α αα αααααΆααααΆαααα
// returns the default account from the Web3 instance initiated previously
function getAddress(web3) {
return web3.eth.getAccounts().then(accounts => accounts[0]);
}
// Deploys the contract using contract's interface and node's default address
async function deployContract(web3) {
const address = await getAddress(web3);
// initiate contract with contract's interface
const contract = new web3.eth.Contract(
temperatureMonitor.interface
);
return contract.deploy({
// deploy contract with contract's bytecode
data: temperatureMonitor.bytecode,
})
.send({
from: address,
gas: '0x2CD29C0',
})
.on('error', console.error)
.then((newContractInstance) => {
// returns deployed contract address
return newContractInstance.options.address;
});
}
call
ΠΈ send
.
αααααααΎαα
αα
α»ααααααααΆαααΈαα»ααα ααΆααα·α
αα
αααααΆαααααααα·ααααα· set
αααααααΎαα·ααΈααΆααααα web3 send
.
// get contract deployed previously
async function getContract(web3, contractAddress) {
const address = await getAddress(web3);
return web3.eth.Contract(
temperatureMonitor.interface,
contractAddress, {
defaultAccount: address,
}
);
}
// calls contract set method to update contract's temperature
async function setTemperature(web3, contractAddress, temp) {
const myContract = await getContract(web3, contractAddress);
return myContract.methods.set(temp).send({}).then((receipt) => {
return receipt.status;
});
}
αααααΆααααΎαααααΎαα·ααΈααΆααααα web3 call
ααΎααααΈααα½αααΆαααΈαα»ααα ααΆααα·α
αα
αααααΆα ααΌαα
αααΆαααΆαα·ααΈααΆααααα call
ααααΌαααΆαααααα·ααααα·αα
ααΎααααΆααααΌαααααΆα α αΎαααααα·ααααα·ααΆαααΉααα·αααααΌαααΆααααααΎααα
ααΎ blockchain ααα
// calls contract get method to retrieve contract's temperature
async function getTemperature(web3, contractAddress) {
const myContract = await getContract(web3, contractAddress);
return myContract.methods.get().call().then(result => result);
}
α₯α‘αΌααααα’αααα’αΆα
αααααΆαα
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3
αααααΆαααα ααΎαα’αΆα ααΎαααΆαα»αα αααα»α Quorum explorer αα αααα»αααααα Chainstack ααΌα αααααΆααααα αΆαααΆααααααα
ααααΆααααΆααααΈααΆαααααΎα’αααααααα α αΎαααααα·ααααα·ααΆαααααΌαααΆαααααΎαα αα α»ααααααααΆαα
- ααααα·ααααα·ααΆαααααΌαααΆαααΆαααααααΆααα·α αα αααααΆα
- ααααα·ααααα·ααΆαααΈααΈααααααααΈαα»ααα ααΆααα·α αα αααααΆααα 3 ααΊααααα
- ααΈαα»ααα ααΆαααααΌαααΆαααα½αααΆααααααααΆααααΌαααααΆα ααΌα ααααααααΆαααααα·ααααα·ααΆαααΆαα½αααααΌαααΆααααααΎαααα
ααααα·ααααα·ααΆαα―ααα
ααα·αα
αααααΌαααΆαααΌαα ααααα’αααααΆαααΊααΆαααΆαααΆααα·ααααααα ααΆα§ααΆα ααα ααΌααα·α αΆαααΆααααΆααΈαααΌαα½ααααα»ααααα ααααΆαααααΎα αα½αααααΆαααααααΆαααααααΆαα»αα’αΆα αΆαααα»αααααΆα ααααα‘ααααΈααααΆα α’αααααα:
- α’αααααα αααααααΎα§αααααα αΆαααααααΆ IoT α’αΆααααααααΈαα»ααα ααΆααααααΆαα 30 αα·ααΆααΈ α αΎααααααΌααα½αααα αα ααααΆαααααΎα;
- αααααααΆααααααα½αααα’αΆα ααααΎααΆα αααα’αααααα ΠΈ αα ααααΆαααααΎααααααΆαααααααααααααα½αα
ααΎαααΉαααααααα·α αα ααΆαααΆαααα½ααααααΆααααα αΆααα αααα»αααααΆααααΆαααΆαααΎα
- ααΎαααααΎααααΆααααΈααΌα ααααΆααΈααααΆααΈαααΌαα»α ααΎααααΈαααα αΆαααΈααααα·ααααα·ααΆαα―αααα
- ααααΆαααααΎα ααΆαααααααΆααα·α αα αααααΆααααΆααααααααΆαααααααα―ααα ααααΆαααααΎα ΠΈ α’αααααα.
- ααΆααΈααΈααΈ αα·αααΆααα·αααα·α αΌαααααΎαα·α αα αααααΆααααΆαααααα
ααΎαααΉαα α
αα·ααΈααΆααααα get
ΠΈ set
αααα»αααΆα ααααΆαααααΎα ΠΈ α’αααααα ααΎααααΈαααα αΆαααΈααααα·ααααα·ααΆαααααΌααα»αα―αααα
-
ααΎαααΉαααΆαααααααΆααα·α αα αααααΆα―ααααααααΆααα’αααα αΌααα½α ααααΆαααααΎα ΠΈ α’αααααα ααΆααααα’αααα αΌααα½α ααααΆαααααΎα:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Contract address after deployment: ${contractAddress}`);
-
ααααααααααΈαα»ααα ααΆαααΈ ααΆααΈβααΈααΈ (ααααΆααααΆααααα ) αα·αααα½αααΆααααααααΈαα»ααα ααΆαα
// Attempts to set Contract temperature to 10, this will not mutate contract's temperature await setTemperature( raft3Node, contractAddress, process.env.PK1, 10, ); // This returns null const temp = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved after updating contract from external nodes: ${temp}`);
-
ααααααααααΈαα»ααα ααΆαααΈ α’αααααα (ααααΆααααΆααααα»α) αα·αααα½αααΆααααααααΈαα»ααα ααΆαα
ααΈαα»ααα ααΆααα αααα»αααααΆααΈαααΌααααα½ααααααα‘ααααααα 12 ααΈαα·α αα αααααΆααααΆαααα ααΌαα αααΆα α’αααααα αα ααΈαααααΆααα·αααα·α αΌαααααΎαα·α αα αααααΆααααΆαααα
// Updated Contract temperature to 12 degrees await setTemperature( raft2Node, contractAddress, process.env.PK1, 12, ); // This returns 12 const temp2 = await getTemperature(raft2Node, contractAddress); console.log(`[Node2] temp retrieved after updating contract from internal nodes: ${temp2}`);
-
ααΎαααα½αααΆαααΈαα»ααα ααΆαααΈ ααΆααΈβααΈααΈ (ααααΆααααΆααααα )α
αα αααα»αααα αΆαααΈ 3 ααΈαα»ααα ααΆαααααΌαααΆαααααααα 12 ααα»αααα ααΆααΈααΈααΈ αα·αααΆααα·αααα·α αΌαααααΎαα·α αα αααααΆααααΆαααααα ααΌα ααααααααααααα‘ααααααΌααααααα
// This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);
αααααΆαα ααΎαααΉααα·αα·αααααΎαααΆαααααα·αααααααα»αααΆαα’αα»ααααααααα·ααααα·ααΆαα―ααααα ααΎαααααΆαααΌααα»αααΆαα½α
ααα ααααα 3.js . αααααΆααααααΌαααΆαα αααΎαααΊααΌα ααααΆαααααΆααααααα·ααααα·ααΆαααΆααΆααα ααΎαααΉαααααα αααααααααΆαααααααααα»αααααΆαααααΆααααααα·ααααα·ααΆαα―αααα
ααΌαα αααΆαααΆαα·α αα αααααΆαααααΆααααα»αα‘αΎααα ααΆαααααααΆαααΊαα·αα’αΆα ααααΆααααααΌαααΆα ααΌα ααααααΆαα αΌαααααΎαααααααΌαααΆαα’αα»ααααΆαααααΌαααααααΌαααΆαααααααα α±ααααααΆααααααααααααααααΎααα·α αα αααααΆααΆααΆααααα ααααα·α αα αααααΆααααΌαααΆαααΆααα±ααααααΎααααΆαα αα·αααααααααΆααααΈαααααα
async function deployContract(web3, publicKey) {
const address = await getAddress(web3);
const contract = new web3.eth.Contract(
temperatureMonitor.interface,
);
return contract.deploy({
data: temperatureMonitor.bytecode,
})
.send({
from: address,
gas: β0x2CD29C0β,
// Grant Permission to Contract by including nodes public keys
privateFor: [publicKey],
})
.then((contract) => {
return contract.options.address;
});
}
ααααα·ααααα·ααΆαα―αααααααΌαααΆαα’αα»ααααααΆαααααααααααααααΆ - ααααααα αΌαααααΆααΆαααααααα’αααα αΌααα½ααα αααααααα·ααααα·α
async function setTemperature(web3, contractAddress, publicKey, temp) {
const address = await getAddress(web3);
const myContract = await getContract(web3, contractAddress);
return myContract.methods.set(temp).send({
from: address,
// Grant Permission by including nodes public keys
privateFor: [publicKey],
}).then((receipt) => {
return receipt.status;
});
}
α₯α‘αΌααααααΎαα’αΆα
αααααΆαα
node private.js
Contract address after deployment: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] temp retrieved after updating contract from external nodes: null
[Node2] temp retrieved after updating contract from internal nodes: 12
[Node3] temp retrieved from external nodes after update null
α’ααααα»αααααΌααα»ααα αααα»α Chainstack ααΉααααα αΆαααΌα ααΆααααααα
- ααΆαααΆαααααααΆααα·α αα αααααΆααΈα’αααα αΌααα½α ααααΆαααααΎα;
- ααΆααααααα
SetTemperature
ααΈ ααΆααΈβααΈααΈ; - ααΆααααααα
SetTemperature
ααΈα’αααα αΌααα½α α’αααααα.
ααΌα αααα’αααα’αΆα ααΎαααααα·ααααα·ααΆαααΆααααΈαααααΌαααΆααααα αα ααα»ααααααΆαααααααα·ααααα·ααΆαααΈα’αααα αΌααα½αααα»αααααα α’αααααα ααααΎαα αα α»ααααααααΆαααΈαα»ααα ααΆααααα»ααα·α αα αααααΆα ααΌα αααα ααααα·ααααα·ααΆαα―ααααααααααΌαααΆααα·αα’αΆα ααααΆααααααΌαααΆα ααα»αααααααα»αααααααα½ααα·αααααΌααααα αΆααα·αααααααααααΆααΈααΈααΈα‘αΎαα
ααα ααααΈααααα·ααααΆα
ααΎαααΆααα·αα·αααααΎαααααΈααααΎααααΆααααΆαα·ααααααααααααΆααααΌααα»αααΎααααΈαααααααααααΆαα’αααΈααΈαα»ααα ααΆαααΆαααααααα αααα»αααααΆαααααααΆαααααααΆααααααΆααααΆαααΆααΈααΈα - ααααΆαααααΎα αα·αααα αΆααααααΆααα
ααΎαααΆααααα αΆαααΈαααααααααααααΆαααΈαα»ααα ααΆαααΆααααααα’αΆα ααααΌαααΆααααααΆαα»αααΆααααααααα·ααααα·ααΆαααΆααααΆααΆααα αα·αα―αααα
ααΆα’αΆα ααΆαααααΆααΈαααΌαααααααα·ααΈααΆα αααΎα α αΎαααΌα αααα’αααααΆαααΎα ααΆαα·ααα·ααΆαααΆαααααααα
ααΆααααα ααααΆααΆααααααΈαααααααΈαααααα’αααα ααΎαααΈααααα
αααα§ααααΆα αααααα
αα
αααα·ααααΆ blockchain
ααααα: www.habr.com