In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the knowledge of "what are the classic design patterns of solidity intelligent contracts". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1. Self-destruct contract
The contract self-destruct mode is used to terminate a contract, which means that the contract will be permanently deleted from the blockchain. Once destroyed, it is not possible to invoke the function of the contract and do not record transactions in the ledger.
The question now is: "Why should I destroy the contract?" .
There are many reasons, such as certain fixed-time contracts, or those that must be terminated once a milestone is reached. A typical case is a loan contract, which should be automatically destroyed after the loan is repaid; another case is a time-based auction contract, which should be terminated after the auction ends-assuming we do not need to keep a history of the auction on the chain.
When dealing with a destroyed contract, there are some issues that need to be noted:
After the contract is destroyed, the transaction sent to the contract will fail
Any funds sent to the destroyed contract will be lost forever.
To avoid financial losses, ensure that the target contract still exists and remove all references to the destroyed contract before sending the funds. Now let's look at the code:
Contract SelfDesctructionContract {public address owner; public string someValue; modifier ownerRestricted {require (owner = = msg.sender); _;} / / constructor function SelfDesctructionContract () {owner = msg.sender;} / / a simple setter function function setSomeValue (string value) {someValue = value;} / / you can call it anything you want function destroyContract () ownerRestricted {suicide (owner);}}
As you can see, the destroyContract () method is responsible for destroying the contract.
Note that we use a custom ownerRestricted modifier to show the caller of this method, that is, only the owner of the contract is allowed to destroy the contract.
2. Factory contract
Factory contracts are used to create and deploy "sub" contracts. These subcontracts can be called "assets" and can represent real-life houses or cars.
The factory is used to store the address of the subcontract for extraction and use if necessary. You might ask, why not store them in the Web application database? This is because storing this address data in the factory contract means it is stored on the block chain, so it is more secure, and the corruption of the database may result in the loss of asset addresses, resulting in the loss of references to these asset contracts. In addition, you need to track all newly created sub-contracts in order to update the database synchronously.
A common use case for factory contracts is to sell assets and track them (for example, who is the owner of the asset). You need to add a payable modifier to the function responsible for deploying the asset to sell the asset. The code is as follows:
Contract CarShop {address [] carAssets; function createChildContract (string brand, string model) public payable {/ / insert check if the sent ether is enough to cover the car asset... Address newCarAsset = newCarAsset (brand, model, msg.sender); carAssets.push (newCarAsset);} function getDeployedChildContracts () public view returns (address []) {return carAssets;}} contract CarAsset {string public brand; string public model; address public owner; function CarAsset (string _ brand, string _ model, address _ owner) public {brand = _ brand; model = _ model; owner = _ owner;}}
Code address newCarAsset = newCarAsset (...) A transaction will be triggered to deploy the subcontract and return the address of the contract. Since the only link between a factory contract and an asset contract is the variable address [] carAssets, it is important to ensure that the address of the subcontract is stored.
3. Name registry
Suppose you are building a DApp that relies on multiple contracts, such as an online mall based on blockchain, which uses multiple contracts such as ClothesFactoryContract, GamesFactoryContract, BooksFactoryContract, and so on.
Now imagine writing the addresses of all these contracts in your application code. What if the addresses of these contracts change over time?
This is what the name registry does, and this pattern allows you to fix only one contract address in your code, rather than dozens, hundreds, or even thousands of addresses. It works by using a mapping table of contract name = > contract address, so you can find the address of each contract from within DApp by calling getAddress ("ClothesFactory"). The advantage of using the name registry is that even if those contracts are updated, DApp will not be affected in any way, because we only need to change the address of the contract in the mapping table.
The code is as follows:
Contract NameRegistry {struct ContractDetails {address owner; address contractAddress; uint16 version;} mapping (string = > ContractDetails) registry; function registerName (string name, address addr, uint16 ver) returns (bool) {/ / versions should start from 1 require (ver > = 1); ContractDetails memory info = registry [name]; require (info.owner = = msg.sender) / / create info if it doesn't exist in the registry if (info.contractAddress = = address (0)) {info = ContractDetails ({owner: msg.sender, contractAddress: addr, version: ver});} else {info.version = ver; info.contractAddress = addr } / / update record in the registry registry [name] = info; return true;} function getContractDetails (string name) constant returns (address, uint16) {return (registry.regitAddress, registry.version);}}
Your DApp will use getContractDetails (name) to get the address and version of the specified contract.
4. Mapping table iterator
Many times we need to iterate over a mapping table, but because the mapping table in Solidity can only store values and does not support iteration, the mapping table iterator pattern is very useful. It is important to note that as the number of members increases, the complexity of iterative operations increases and storage costs increase, so avoid iterations as much as possible.
The implementation code is as follows:
Contract MappingIterator {mapping (string = > address) elements; string [] keys; function put (string key, address addr) returns (bool) {bool exists = elements [key] = = address (0) if (! exists) {keys.push (key);} elements [key] = addr; return true;} function getKeyCount () constant returns (uint) {return keys.length } function getElementAtIndex (uint index) returns (address) {return elements [keys];} function getElement (string name) returns (address) {return elements [name];}}
A common mistake in implementing the put () function is to check the existence of the specified key by traversing. The correct thing to do is elements [key] = = address (0). Although traversing the check is not entirely an error, it is not desirable because iterations become more and more expensive as the keys array grows, so iterations should be avoided as much as possible.
5. Withdrawal mode
Suppose you sell car tires, and unfortunately there is something wrong with all the tires sold, so you decide to refund all the buyers.
Suppose you track all the buyers in the contract, and the contract has a refund () function that traverses all the buyers and returns the money one by one.
You can choose-use buyerAddress.transfer () or buyerAddress.send (). The difference between these two functions is that when trading an exception, send () does not throw an exception, but just returns a Boolean value of false, while transfer () throws an exception.
Why is this important?
Assume that most buyers are external accounts (that is, individuals), but some buyers are other contracts (perhaps commercial). Suppose there is a contract in which the developer makes an error in its fallback function and throws an exception when called. The fallback () function is the default function in the contract. If a transaction is sent to the contract but no method is specified, the contract's fallback () function will be called. Now, as long as we call contractWithError.transfer () in the refund function, we throw an exception and stop iterating. Therefore, the fallback () exception of any buyer's contract will cause the entire refund transaction to be rolled back, resulting in no buyer getting a refund.
Although all buyers can use send () to refund in one call, a better way is to provide a withdrawFunds () method, which will be refunded to the caller separately as needed. Therefore, the wrong contract will not apply to other buyers to get a refund.
The implementation code is as follows:
Contract WithdrawalContract {mapping (address = > uint) buyers; function buy () payable {require (msg.value > 0); buyers [msg.sender] = msg.value;} function withdraw () {uint amount = buyers [msg.sender]; require (amount > 0); buyers [msg.sender] = 0; require (msg.sender.send (amount)) This is the end of the introduction of "what are the classic design patterns of the solidity intelligent contract". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.