์ฟผ๋ผ์ ๊ฐ์ธ ๋ฐ ๊ณต์ฉ ํธ๋์ญ์ ์ ์ง์ํ๋ฉฐ ๋ง์ ์์ ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ณด์ ํ๊ณ ์์ต๋๋ค.
์ด ๊ธฐ์ฌ์์๋ ์ฐฝ๊ณ ์จ๋์ ๋ํ ์ต์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ์ํผ๋ง์ผ๊ณผ ์ฐฝ๊ณ ์์ ์ ์ฌ์ด์ ๋ถ์ฐ ์์ฅ ๋คํธ์ํฌ๋ฅผ ๋ฐฐํฌํ๋ ์๋๋ฆฌ์ค ์ค ํ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ด ํํ ๋ฆฌ์ผ์์ ์ฌ์ฉ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ด ๊ธฐ์ฌ์์๋ ๋ค์ ๋ด์ฉ์ ๋ค๋ฃน๋๋ค.
- ์ค๋งํธ ๊ณ์ฝ ์์ฑ;
- ๋ค์์ ์ฌ์ฉํ์ฌ Quorum ๋คํธ์ํฌ ๋ฐฐํฌ
์ฒด์ธ ์คํ ; - ์ฟผ๋ผ ๊ณต๊ฐ ํธ๋์ญ์
- ์ฟผ๋ผ ๋น๊ณต๊ฐ ํธ๋์ญ์ .
์ค๋ช ์ ์ํด IoT(์ฌ๋ฌผ ์ธํฐ๋ท) ๋ด Quorum ๋คํธ์ํฌ ๊ตฌ์ฑ์์ ์ฐฝ๊ณ ์จ๋๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ์๋๋ฆฌ์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ฌธ๋งฅ
์ฐฝ๊ณ ํ์ฌ ๊ทธ๋ฃน์ด ์ปจ์์์์ผ๋ก ์ฐํฉํ์ฌ ๋ธ๋ก์ฒด์ธ์ ์ ๋ณด๋ฅผ ๊ณต๋์ผ๋ก ์ ์ฅํ๊ณ ํ๋ก์ธ์ค๋ฅผ ์๋ํํ๊ณ ์์ต๋๋ค. ์ด๋ฅผ ์ํด ๊ธฐ์ ์์๋ Quorum์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ๊ณต๊ฐ ๊ฑฐ๋์ ๋น๊ณต๊ฐ ๊ฑฐ๋๋ผ๋ ๋ ๊ฐ์ง ์๋๋ฆฌ์ค๋ฅผ ๋ค๋ฃน๋๋ค.
๊ฑฐ๋๋ ์์ ์ด ์ํ ์ปจ์์์๊ณผ ์ํธ ์์ฉํ๊ธฐ ์ํด ๋ค์ํ ์ฐธ๊ฐ์์ ์ํด ์์ฑ๋ฉ๋๋ค. ๊ฐ ํธ๋์ญ์ ์ ๊ณ์ฝ์ ๋ฐฐํฌํ๊ฑฐ๋ ๊ณ์ฝ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋คํธ์ํฌ์ ์ ๋ก๋ํฉ๋๋ค. ์ด๋ฌํ ์์ ์ ๋คํธ์ํฌ์ ๋ชจ๋ ๋ ธ๋์ ๋ณต์ ๋ฉ๋๋ค.
๊ณต๊ฐ ๊ฑฐ๋๋ ๋ชจ๋ ์ปจ์์์ ์ฐธ๊ฐ์๊ฐ ๋ณผ ์ ์์ต๋๋ค. ๊ฐ์ธ ๊ฑฐ๋๋ ๊ธฐ๋ฐ์ฑ์ ์ถ๊ฐํ๋ฉฐ ๊ทธ๋ ๊ฒ ํ ๊ถ๋ฆฌ๊ฐ ์๋ ์ฐธ๊ฐ์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ ์๋๋ฆฌ์ค ๋ชจ๋ ๋ช ํ์ฑ์ ์ํด ๋์ผํ ๊ณ์ฝ์ ์ฌ์ฉํฉ๋๋ค.
๋๋ํ ๊ณ์ฝ
๋ค์์ ์ฐ๋ฆฌ ์๋๋ฆฌ์ค๋ฅผ ์ํด ์์ฑ๋ ๊ฐ๋จํ ์ค๋งํธ ๊ณ์ฝ์
๋๋ค. ๊ณต๊ฐ ๋ณ์๊ฐ ์์ต๋๋ค 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
์ด์ ๊ณ์ฝ์ด ์ค๋น๋์์ผ๋ฏ๋ก ๋คํธ์ํฌ๋ฅผ ๋ฐฐํฌํ๊ณ ๊ณ์ฝ์ ๋ฐฐํฌํ๊ฒ ์ต๋๋ค.
๋ ธ๋ ๋ฐฐํฌ
๋
ธ๋ ๋ฐฐํฌ๋ ์๋นํ ๋
ธ๋ ์ง์ฝ์ ์ผ ์ ์์ผ๋ฉฐ ์ด ํ๋ก์ธ์ค๋ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋์ฒด๋ ์ ์์ต๋๋ค.
๋ค์์ Raft ํฉ์์ XNUMX๊ฐ์ ๋ ธ๋๋ฅผ ์ฌ์ฉํ์ฌ Quorum ๋คํธ์ํฌ๋ฅผ ๋ฐฐํฌํ๋ ํ๋ก์ธ์ค์ ๋๋ค.
๋จผ์ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๊ณ Quorum Project๋ผ๊ณ ๋ถ๋ฅด๊ฒ ์ต๋๋ค.
Google Cloud Platform์์ Raft ํฉ์๋ฅผ ์ฌ์ฉํ์ฌ Quorum ๋คํธ์ํฌ๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฏธ ์์ฑ๋ ๋ ธ๋์ ๋ ๊ฐ์ ๋ ธ๋๋ฅผ ๋ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
์คํ ์ค์ธ ๋ ธ๋ XNUMX๊ฐ:
๋ ธ๋ ์ธ๋ถ์ ๋ณด ํ์ด์ง์๋ 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);
๋ค์์ผ๋ก, ๋ค์์ ์ฌ์ฉํ์ฌ Quorum ๋คํธ์ํฌ์์ ๊ณต๊ฐ ํธ๋์ญ์ ์ ์คํํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์น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
๋ก์ปฌ ๋
ธ๋์์ ์คํ๋๋ฉฐ ํธ๋์ญ์
์ ๋ธ๋ก์ฒด์ธ์์ ์์ฑ๋์ง ์์ต๋๋ค.
// 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
๋ค์์ผ๋ก ์๋์ ๊ฐ์ด Chainstack ํจ๋์ Quorum ํ์๊ธฐ์์ ํญ๋ชฉ์ ๋ณผ ์ ์์ต๋๋ค.
์ธ ๋ ธ๋๊ฐ ๋ชจ๋ ์ํธ ์์ฉํ๊ณ ํธ๋์ญ์ ์ด ์ ๋ฐ์ดํธ๋์์ต๋๋ค.
- ์ฒซ ๋ฒ์งธ ๊ฑฐ๋๋ ๊ณ์ฝ์ ๋ฐฐํฌํ์ต๋๋ค.
- ๋ ๋ฒ์งธ ํธ๋์ญ์ ์์๋ ๊ณ์ฝ ์จ๋๋ฅผ 3๋๋ก ์ค์ ํ์ต๋๋ค.
- ์จ๋๋ ๋ก์ปฌ ๋ ธ๋๋ฅผ ํตํด ์์ ๋๋ฏ๋ก ํธ๋์ญ์ ์ด ์์ฑ๋์ง ์์ต๋๋ค.
๊ฐ์ธ ๊ฑฐ๋
๋ฌธ๋งฅ
์กฐ์ง์ ์ผ๋ฐ์ ์ธ ์๊ตฌ ์ฌํญ์ ๋ฐ์ดํฐ ๋ณดํธ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณด์ญ์์ค. ์ํผ๋ง์ผ ํด์ฐ๋ฌผ์ ๋ณด๊ดํ๊ธฐ ์ํ ์ฐฝ๊ณ ๊ณต๊ฐ์ ๋ณ๋๋ก ์๋ํฉ๋๋ค. ๊ณต๊ธ์ ์ฒด:
- ๊ณต๊ธ์ ์ฒด IoT ์ผ์๋ฅผ ์ด์ฉํด 30์ด๋ง๋ค ์จ๋๊ฐ์ ์ฝ์ด ์ ์กํ๋ค. ์ํผ๋ง์ผ์ผ๋ก;
- ์ด ๊ฐ์ ๋ง ์ฌ์ฉํ ์ ์์ด์ผํฉ๋๋ค ํ๋งค์์๊ฒ ะธ ์ํผ๋ง์ผ์ผ๋ก, ์ปจ์์์์ผ๋ก ๋คํธ์ํฌํ๋จ.
์ ๋ค์ด์ด๊ทธ๋จ์ ํ์๋ ๋ค ๊ฐ์ง ์์ ์ ์๋ฃํ๊ฒ ์ต๋๋ค.
- ์ด์ ์๋๋ฆฌ์ค์ ๋์ผํ ์ธ ๊ฐ์ ๋ ธ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ธ ํธ๋์ญ์ ์ ๋ณด์ฌ์ค๋๋ค.
- ์ํผ๋ง์ผ ๋น๊ณต๊ฐ ์ค๋งํธ ๊ณ์ฝ์ ๋ฐฐํฌํฉ๋๋ค. ์ํผ๋ง์ผ ะธ ๊ณต๊ธ์ ์ฒด.
- ์ธ ๋ฒ์งธ ์ธก๋ฉด ์ค๋งํธ ๊ณ์ฝ์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ด ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒ์
๋๋ค get
ะธ set
๋์ ์ ์ํผ๋ง์ผ ะธ ๊ณต๊ธ์
์ฒด ๋น๊ณต๊ฐ ์ฟผ๋ผ ํธ๋์ญ์
์ ๋ณด์ฌ์ค๋๋ค.
-
์ฐธ๊ฐ์๋ฅผ ์ํ ๋น๊ณต๊ฐ ๊ณ์ฝ์ ๋ฐฐํฌํฉ๋๋ค. ์ํผ๋ง์ผ ะธ ๊ณต๊ธ์ ์ฒด ์ฐธ๊ฐ์๋ฅผ ํตํด ์ํผ๋ง์ผ:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Contract address after deployment: ${contractAddress}`);
-
์จ๋๋ถํฐ ์ค์ ํ์ ์ XNUMX์ (์ธ๋ถ ๋ ธ๋) ์จ๋ ๊ฐ์ ์ป์ต๋๋ค.
// 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}`);
-
์ฐ๋ฆฌ๋ ์จ๋๋ฅผ ์ป์ต๋๋ค. ์ XNUMX์ (์ธ๋ถ ๋ ธ๋):
3๋จ๊ณ์์๋ ์จ๋๋ฅผ 12๋๋ก ์ค์ ํ์ง๋ง ์ธ ๋ฒ์งธ ์ธก๋ฉด ์ค๋งํธ ๊ณ์ฝ์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฐํ ๊ฐ์ null์ด์ด์ผ ํฉ๋๋ค.
// This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);
๋ค์์ผ๋ก Quorum ๋คํธ์ํฌ์์ ๊ฐ์ธ ํธ๋์ญ์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์น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์ Quorum ํ์๊ธฐ์๋ ๋ค์์ด ํ์๋ฉ๋๋ค.
- ์ฐธ๊ฐ์์ ๊ณ์ฝ ๋ฐฐํฌ ์ํผ๋ง์ผ;
- ์คํ
SetTemperature
๋ถํฐ ์ XNUMX์; - ์คํ
SetTemperature
์ฐธ๊ฐ์๋ก๋ถํฐ ๊ณต๊ธ์ ์ฒด.
๋ณด์๋ค์ํผ ๋ ํธ๋์ญ์ ๋ชจ๋ ์๋ฃ๋์์ง๋ง ์ฐธ๊ฐ์์ ํธ๋์ญ์ ๋ง ์๋ฃ๋์์ต๋๋ค. ๊ณต๊ธ์ ์ฒด ๊ณ์ฝ์์ ์จ๋๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ธ ๊ฑฐ๋๋ ๋ถ๋ณ์ฑ์ ์ ๊ณตํ์ง๋ง ๋์์ ์ XNUMX์์๊ฒ ๋ฐ์ดํฐ๋ฅผ ๊ณต๊ฐํ์ง ์์ต๋๋ค.
๊ฒฐ๋ก
์ฐ๋ฆฌ๋ ์ํผ๋ง์ผ๊ณผ ์ฐฝ๊ณ ์์ ์๋ผ๋ ๋ ๋น์ฌ์ ์ฌ์ด์ ๋คํธ์ํฌ๋ฅผ ๋ฐฐํฌํ์ฌ ์ฐฝ๊ณ ์ ์ต์ ์จ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ Quorum์ ์์ ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ดํด๋ณด์์ต๋๋ค.
์ฐ๋ฆฌ๋ ๊ณต๊ฐ ๋ฐ ๋น๊ณต๊ฐ ๊ฑฐ๋๋ฅผ ํตํด ์ด๋ป๊ฒ ์ต์ ์จ๋ ์ ๋ณด๋ฅผ ์ ์งํ ์ ์๋์ง ๋ณด์ฌ์ฃผ์์ต๋๋ค.
๋ง์ ์์ฉ ์๋๋ฆฌ์ค๊ฐ ์์ ์ ์์ผ๋ฉฐ ๋ณด์๋ค์ํผ ์ ํ ์ด๋ ต์ง ์์ต๋๋ค.
์คํํ๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฅํด ๋ณด์ธ์. ๋ํ, ๋ธ๋ก์ฒด์ธ ๊ธฐ์ ์ฐ์
์
์ถ์ฒ : habr.com