Solidity'nin diğer sözleşmeleriyle etkileşime geçin
Önceki öğreticilerde ilk akıllı sözleşmenizi nasıl dağıtacağınızla ve ona nasıl niteleyicilerle erişim kontrolü(opens in a new tab) veya Solidity'de hata işleme(opens in a new tab) gibi bazı özellikler ekleyeceğinizle ilgili çok şey öğrendik. Bu öğreticide, mevcut bir sözleşmeden akıllı bir sözleşmenin nasıl dağıtılacağını ve onunla nasıl etkileşime geçileceğini öğreneceğiz.
Bunun için bir fabrika oluşturarak herkesin kendi Counter
(Sayaç) akıllı sözleşmesine sahip olmasını sağlayan bir sözleşme yapacağız, adı CounterFactory
(Sayaç Fabrikası) olacak. İlk olarak, ilk Counter
akıllı sözleşmemizin kodu:
1pragma solidity 0.5.17;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "You're not the owner of the contract");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "You need to use the factory");17 _;18 }1920 constructor(address owner) public {21 _owner = owner;22 _factory = msg.sender;23 }2425 function getCount() public view returns (uint256) {26 return _count;27 }2829 function increment(address caller) public onlyFactory onlyOwner(caller) {30 _count++;31 }3233}Tümünü gösterKopyala
Fabrikanın adresini ve sözleşme sahibinin adresini takip etmek için sözleşme kodunu biraz değiştirdiğimizi unutmayın. Başka bir sözleşmeden bir sözleşme kodunu aradığınızda, msg.sender sözleşmeli fabrikamızın adresine başvuracaktır. Diğer sözleşmelerle etkileşim kurmak için bir sözleşme kullanmak yaygın bir uygulama olduğundan, bu anlaşılması gerçekten önemli bir noktadır. Bu nedenle, karmaşık durumlarda gönderenin kim olduğuna dikkat etmelisiniz.
Bunun için ayrıca, durum değiştirme işlevinin yalnızca orijinal çağrı yapan parametre olarak geçirecek olan fabrika tarafından çağrılabilmesini sağlayan bir onlyFactory
niteleyicisi ekledik.
Diğer tüm Counter'ları yönetecek olan yeni CounterFactory
'nin içine, bir sahibi karşı sözleşmenin adresiyle ilişkilendirecek bir eşleştirme ekleyeceğiz:
1mapping(address => Counter) _counters;Kopyala
Ethereum'da eşleştirme, javascript'teki nesnelerin eş değeridir, A tipi bir anahtarı B tipi bir değere eşlemeyi sağlar. Bu durumda, bir sahibinin adresini Counter'ın örneğiyle eşleştiririz.
Birisi için yeni bir Counter başlatmak şöyle görünür:
1 function createCounter() public {2 require (_counters[msg.sender] == Counter(0));3 _counters[msg.sender] = new Counter(msg.sender);4 }Kopyala
Önce kişinin zaten bir counter'ı olup olmadığını kontrol ediyoruz. Eğer bir counter'ı yoksa, adresini Counter
yapıcısına ileterek yeni bir counter başlatırız ve yeni oluşturulan örneği eşleştirmeye atarız.
Belirli bir Counter'ın sayısını almak için şöyle görünür:
1function getCount(address account) public view returns (uint256) {2 require (_counters[account] != Counter(0));3 return (_counters[account].getCount());4}56function getMyCount() public view returns (uint256) {7 return (getCount(msg.sender));8}Kopyala
İlk işlev, belirli bir adres için Counter sözleşmesinin var olup olmadığını kontrol eder ve ardından örnekten getCount
yöntemini çağırır. İkinci fonksiyon: getMyCount
sadece getCount
fonksiyonuna doğrudan msg.sender geçirmek için bir kısayoldur.
increment
fonksiyonu oldukça benzerdir ancak orijinal işlem göndericisini Counter
sözleşmesine iletir:
1function increment() public {2 require (_counters[msg.sender] != Counter(0));3 Counter(_counters[msg.sender]).increment(msg.sender);4 }Kopyala
Birçok kez aranırsa, counter'ımızın muhtemelen bir taşma kurbanı olabileceğini unutmayın. Bu olası durumdan korunmak için mümkün olduğunca SafeMath kütüphanesini(opens in a new tab) kullanmalısınız.
Sözleşmemizi dağıtmak için hem CounterFactory
kodunu hem de Counter
kodunu sağlamanız gerekir. Örneğin Remix'te dağıtırken CounterFactory'yi seçmeniz gerekir.
Tam kod burada:
1pragma solidity 0.5.17;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "You're not the owner of the contract");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "You need to use the factory");17 _;18 }1920 constructor(address owner) public {21 _owner = owner;22 _factory = msg.sender;23 }2425 function getCount() public view returns (uint256) {26 return _count;27 }2829 function increment(address caller) public onlyFactory onlyOwner(caller) {30 _count++;31 }3233}3435contract CounterFactory {3637 mapping(address => Counter) _counters;3839 function createCounter() public {40 require (_counters[msg.sender] == Counter(0));41 _counters[msg.sender] = new Counter(msg.sender);42 }4344 function increment() public {45 require (_counters[msg.sender] != Counter(0));46 Counter(_counters[msg.sender]).increment(msg.sender);47 }4849 function getCount(address account) public view returns (uint256) {50 require (_counters[account] != Counter(0));51 return (_counters[account].getCount());52 }5354 function getMyCount() public view returns (uint256) {55 return (getCount(msg.sender));56 }5758}Tümünü gösterKopyala
Derlemeden sonra, Remix dağıtımı bölümünde dağıtılacak fabrikayı seçeceksiniz:
Ardından sözleşmeli fabrikanızla oynayabilir ve değerin değiştiğini kontrol edebilirsiniz. Akıllı sözleşmeyi farklı bir adresten aramak isterseniz, Remix'in Hesap seçiminde adresi değiştirmeniz gerekir.
Son düzenleme: @nhsz(opens in a new tab), 15 Ağustos 2023