प्रमुख मजकुराकडे जा

Solidity मधून इतर कॉन्ट्रॅक्ट्सशी संवाद साधा

स्मार्ट कॉन्ट्रॅक्ट
सॉलिडिटी
रीमिक्स
डिप्लॉयिंग
कंपोझेबिलिटी
प्रगत
jdourlens
५ एप्रिल, २०२०
4 मिनिट वाचन

मागील ट्यूटोरियल्समध्ये आपण बरेच काही शिकलो तुमचा पहिला स्मार्ट कॉन्ट्रॅक्ट कसा डिप्लॉय करायचा आणि त्यात काही वैशिष्ट्ये कशी जोडायची जसे की मॉडिफायर्ससह ऍक्सेस नियंत्रित करणे (opens in a new tab) किंवा Solidity मध्ये त्रुटी हाताळणे (opens in a new tab). या ट्यूटोरियलमध्ये, आपण विद्यमान कॉन्ट्रॅक्टमधून स्मार्ट कॉन्ट्रॅक्ट कसे डिप्लॉय करावे आणि त्याच्याशी संवाद कसा साधावा हे शिकू.

आम्ही एक कॉन्ट्रॅक्ट बनवू जो कोणालाही त्याचा स्वतःचा Counter स्मार्ट कॉन्ट्रॅक्ट तयार करण्यास सक्षम करेल, त्यासाठी एक फॅक्टरी तयार करून, त्याचे नाव CounterFactory असेल. सर्वप्रथम, आमच्या सुरुवातीच्या Counter स्मार्ट कॉन्ट्रॅक्टचा कोड येथे आहे:

1pragma solidity 0.5.17;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
सर्व दाखवा

लक्षात घ्या की फॅक्टरीचा ॲड्रेस आणि कॉन्ट्रॅक्ट मालकाचा ॲड्रेस यांचा मागोवा ठेवण्यासाठी आम्ही कॉन्ट्रॅक्ट कोडमध्ये थोडा बदल केला आहे. जेव्हा तुम्ही दुसऱ्या कॉन्ट्रॅक्टमधून कॉन्ट्रॅक्ट कोडला कॉल करता, तेव्हा msg.sender आमच्या कॉन्ट्रॅक्ट फॅक्टरीच्या ॲड्रेसचा संदर्भ देईल. हा समजून घेण्यासाठी एक खरोखर महत्त्वाचा मुद्दा आहे कारण इतर कॉन्ट्रॅक्ट्सशी संवाद साधण्यासाठी कॉन्ट्रॅक्ट वापरणे ही एक सामान्य प्रथा आहे. त्यामुळे, गुंतागुंतीच्या प्रकरणांमध्ये सेंडर कोण आहे याची आपण काळजी घेतली पाहिजे.

यासाठी आम्ही एक onlyFactory मॉडिफायर देखील जोडला आहे जो हे सुनिश्चित करतो की स्टेट बदलणारे फंक्शन फक्त फॅक्टरीद्वारे कॉल केले जाऊ शकते, जे मूळ कॉलरला पॅरामीटर म्हणून पास करेल.

आमच्या नवीन CounterFactory च्या आत, जे इतर सर्व काउंटर्स व्यवस्थापित करेल, आम्ही एक मॅपिंग जोडू जे मालकाला त्याच्या काउंटर कॉन्ट्रॅक्टच्या ॲड्रेसशी जोडेल:

1mapping(address => Counter) _counters;

Ethereum मध्ये, मॅपिंग हे javascript मधील ऑब्जेक्ट्सच्या समतुल्य आहेत, ते A प्रकारच्या की ला B प्रकारच्या व्हॅल्यूवर मॅप करण्यास सक्षम करतात. या प्रकरणात आपण मालकाच्या ॲड्रेसला त्याच्या काउंटरच्या इन्स्टन्ससह मॅप करतो.

कोणासाठीही नवीन काउंटर सुरू करणे असे दिसेल:

1 function createCounter() public {
2 require (_counters[msg.sender] == Counter(0));
3 _counters[msg.sender] = new Counter(msg.sender);
4 }

आम्ही प्रथम तपासतो की त्या व्यक्तीकडे आधीपासूनच काउंटर आहे की नाही. जर त्याच्याकडे काउंटर नसेल, तर आम्ही त्याचा ॲड्रेस Counter कन्स्ट्रक्टरला पास करून एक नवीन काउंटर सुरू करतो आणि नव्याने तयार केलेला इन्स्टन्स मॅपिंगला नियुक्त करतो.

विशिष्ट काउंटरची गणना मिळविण्यासाठी ते असे दिसेल:

1function getCount(address account) public view returns (uint256) {
2 require (_counters[account] != Counter(0));
3 return (_counters[account].getCount());
4}
5
6function getMyCount() public view returns (uint256) {
7 return (getCount(msg.sender));
8}

पहिले फंक्शन तपासते की दिलेल्या ॲड्रेससाठी काउंटर कॉन्ट्रॅक्ट अस्तित्वात आहे की नाही आणि नंतर इन्स्टन्समधून getCount पद्धत कॉल करते. दुसरे फंक्शन: getMyCount हे getCount फंक्शनला थेट msg.sender पास करण्यासाठी एक छोटा मार्ग आहे.

increment फंक्शन बऱ्यापैकी समान आहे परंतु मूळ ट्रान्झॅक्शन सेंडरला Counter कॉन्ट्रॅक्टकडे पास करते:

1function increment() public {
2 require (_counters[msg.sender] != Counter(0));
3 Counter(_counters[msg.sender]).increment(msg.sender);
4 }

लक्षात घ्या की जर खूप वेळा कॉल केला गेला, तर आमचा काउंटर संभाव्यतः ओव्हरफ्लोचा बळी ठरू शकतो. या संभाव्य प्रकरणापासून संरक्षण करण्यासाठी आपण शक्य तितके SafeMath लायब्ररी (opens in a new tab) वापरली पाहिजे.

आमचा कॉन्ट्रॅक्ट डिप्लॉय करण्यासाठी, तुम्हाला CounterFactory आणि Counter या दोन्हीचा कोड प्रदान करणे आवश्यक असेल. उदाहरणार्थ Remix मध्ये डिप्लॉय करताना तुम्हाला CounterFactory निवडण्याची आवश्यकता असेल.

येथे संपूर्ण कोड आहे:

1pragma solidity 0.5.17;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
34
35contract CounterFactory {
36
37 mapping(address => Counter) _counters;
38
39 function createCounter() public {
40 require (_counters[msg.sender] == Counter(0));
41 _counters[msg.sender] = new Counter(msg.sender);
42 }
43
44 function increment() public {
45 require (_counters[msg.sender] != Counter(0));
46 Counter(_counters[msg.sender]).increment(msg.sender);
47 }
48
49 function getCount(address account) public view returns (uint256) {
50 require (_counters[account] != Counter(0));
51 return (_counters[account].getCount());
52 }
53
54 function getMyCount() public view returns (uint256) {
55 return (getCount(msg.sender));
56 }
57
58}
सर्व दाखवा

कम्पाइल केल्यानंतर, Remix डिप्लॉय विभागात तुम्ही डिप्लॉय करण्यासाठी फॅक्टरी निवडाल:

Remix मध्ये डिप्लॉय करण्यासाठी फॅक्टरी निवडणे

त्यानंतर तुम्ही तुमच्या कॉन्ट्रॅक्ट फॅक्टरीसोबत खेळू शकता आणि बदलणारे मूल्य तपासू शकता. तुम्हाला स्मार्ट कॉन्ट्रॅक्टला वेगळ्या ॲड्रेसवरून कॉल करायचा असल्यास, तुम्हाला Remix च्या अकाउंट निवडीमध्ये ॲड्रेस बदलावा लागेल.

पृष्ठ अखेरचे अद्यतन: १५ ऑगस्ट, २०२३

हे मार्गदर्शन उपयुक्त होते का?