Quorum รองรับธุรกรรมส่วนตัวและสาธารณะ และมีกรณีการใช้งานเชิงพาณิชย์มากมาย
ในบทความนี้ เราจะตรวจสอบสถานการณ์หนึ่งดังกล่าว นั่นคือ การใช้เครือข่ายบัญชีแยกประเภทแบบกระจายระหว่างซูเปอร์มาร์เก็ตและเจ้าของคลังสินค้า เพื่อให้ข้อมูลล่าสุดเกี่ยวกับอุณหภูมิของคลังสินค้า
รหัสที่ใช้ในบทช่วยสอนนี้อยู่ใน
บทความนี้ครอบคลุมถึง:
- การสร้างสัญญาอัจฉริยะ
- การใช้งานเครือข่าย Quorum โดยใช้
โซ่ ; - การทำธุรกรรมสาธารณะองค์ประชุม;
- ธุรกรรมส่วนตัวของโควรัม
เพื่อแสดงให้เห็น เราใช้สถานการณ์จำลองในการตรวจสอบอุณหภูมิในคลังสินค้าของสมาชิกของเครือข่าย Quorum ภายใน Internet of Things (IoT)
สิ่งแวดล้อม
กลุ่มบริษัทคลังสินค้ากำลังรวมตัวกันในกลุ่มเพื่อร่วมกันจัดเก็บข้อมูลและทำให้กระบวนการอัตโนมัติบนบล็อกเชน ด้วยเหตุนี้ บริษัทต่างๆ จึงตัดสินใจใช้ 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
เมื่อสัญญาพร้อมแล้ว เราจะปรับใช้เครือข่ายและปรับใช้สัญญา
การปรับใช้โหนด
การปรับใช้โหนดอาจต้องใช้แรงงานมาก และกระบวนการนี้สามารถแทนที่ได้ด้วยการใช้บริการ
ด้านล่างนี้เป็นกระบวนการปรับใช้เครือข่าย Quorum ด้วยความเห็นพ้องต้องกันของ Raft และโหนดสามโหนด
ขั้นแรก เรามาสร้างโปรเจ็กต์และเรียกมันว่า Quorum Project:
มาสร้างเครือข่าย Quorum ด้วยความเห็นพ้องต้องกันของ Raft บน 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);
ต่อไป เราจะดูวิธีดำเนินการธุรกรรมสาธารณะบนเครือข่าย 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
ต่อไป เราจะดูรายการใน 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}`);
ต่อไปเราจะมาดูการทำธุรกรรมส่วนตัวบนเครือข่าย 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
Quorum explorer ใน Chainstack จะแสดงสิ่งต่อไปนี้:
- การปรับใช้สัญญาจากผู้เข้าร่วม ซูเปอร์มาร์เก็ต;
- การปฏิบัติ
SetTemperature
จาก บุคคลที่สาม; - การปฏิบัติ
SetTemperature
จากผู้เข้าร่วม ผู้ขาย.
อย่างที่คุณเห็นธุรกรรมทั้งสองเสร็จสมบูรณ์แล้ว แต่มีเพียงธุรกรรมจากผู้เข้าร่วมเท่านั้น ผู้ขาย ปรับปรุงอุณหภูมิในสัญญา ดังนั้นธุรกรรมส่วนตัวจึงทำให้เกิดความไม่เปลี่ยนแปลง แต่ในขณะเดียวกันก็ไม่เปิดเผยข้อมูลต่อบุคคลที่สาม
ข้อสรุป
เราพิจารณากรณีการใช้งานเชิงพาณิชย์ของ Quorum เพื่อให้ข้อมูลอุณหภูมิที่ทันสมัยในคลังสินค้าโดยการปรับใช้เครือข่ายระหว่างสองฝ่าย - ซูเปอร์มาร์เก็ตและเจ้าของคลังสินค้า
เราแสดงให้เห็นว่าสามารถรักษาข้อมูลอุณหภูมิที่ทันสมัยผ่านธุรกรรมทั้งภาครัฐและเอกชนได้อย่างไร
อาจมีสถานการณ์การใช้งานได้มากมาย และอย่างที่คุณเห็น มันไม่ยากเลย
ทดลองลองขยายสคริปต์ของคุณ นอกจากนี้อุตสาหกรรมเทคโนโลยีบล็อคเชน
ที่มา: will.com