Can a Public Contract Know All Its Content?
No.
- Contracts have private variables. The term "private" means that the information is not intended to be disclosed, and outsiders cannot access it.
- The creation code contains all the content, but it is very difficult to parse into readable information. For example, it is hard to extract initialization parameters:
- This includes whether the developer intended it to be this way.
- Compiler optimizations and encryption also play a role.
How to Deploy a Contract with Multiple Files
A contract is generally a single file with a clear contract name representing the main contract. It can import multiple files, and methods from different files may also be parsed into callable ABIs.
To call an externally deployed contract, you can set the address of the external contract in the current contract and use an interface to link to and call the contract.
A library can be deployed as a separate contract. When deploying a library, you only need to link it without deploying it separately.
"libraries": {
"contracts/libraries/NFTDescriptor.sol": {
"NFTDescriptor": "0x42b24a95702b9986e82d421cc3568932790a48ec"
}
}
In Solidity, when a contract references a library, the compiler generates a placeholder address to mark the location of the library in the contract code. Before deploying the contract, this placeholder address must be replaced with the actual address of the deployed library. This process is called "library linking."
Keywords
Exposing contract methods:
public
external
(callable only from outside)
memory
indicates that a variable is not stored persistently but exists only in memory.
abi
is a built-in library provided by Solidity.
abi.encode
encodes multiple values into a byte array.abi.encodePacked
encodes multiple values into a tightly packed byte array without alignment or padding.abi.encodeWithSelector
encodes a function selector (4 bytes) and parameters into a byte array. It is commonly used for calling contract functions.abi.encodeWithSignature
encodes a function signature (in string form) and parameters into a byte array. The compiler automatically parses the function signature to generate the selector.abi.decode
decodes a byte array into variables of specified types. The types to be decoded must be specified.abi.encodeCall
encodes a function call into a byte array. This method is available in Solidity version 0.8.12 and above, making it easier to encode function calls.abi.selector
retrieves the function selector (4 bytes). This method is available in Solidity version 0.8.12 and above.abi.functionSelector
retrieves the function selector (4 bytes). This method is available in Solidity version 0.8.12 and above, similar toabi.selector
.
Compiler Optimization
In the Solidity compilation process, optimization is an important option that helps optimize the generated bytecode, thereby reducing gas consumption during deployment and execution. Enabling optimization typically involves a series of improvements to the code generated by the compiler to enhance efficiency.
Optimization Enabled: Yes with 200 runs
solc --optimize --optimize-runs 200 your_contract.sol
Uniswap tokenURI
tokenURI
is dynamically generated data that wraps position data into a JSON data encoded in Base64. When parsing, WETH9 is handled specially.
Base64
Base64 converts characters into 8-bit binary (0/1
), then reassembles them into 6-bit binary, mapping to ASCII characters. The length is a multiple of 4, with =
used for padding at the end.
Parent Class Initialization
constructor([parameter list]) [parent contract constructor call] {
// Initialization logic
}
constructor(
address _factory,
address _WETH9,
address _tokenDescriptor_
) ERC721Permit('Uniswap V3 Positions NFT-V1', 'UNI-V3-POS', '1') PeripheryImmutableState(_factory, _WETH9) {
_tokenDescriptor = _tokenDescriptor_;
}
Modifiers
function collect(CollectParams calldata params)
external
payable
override
isAuthorizedForToken(params.tokenId)
returns (uint256 amount0, uint256 amount1)
{
// ...
}
modifier isAuthorizedForToken(uint256 tokenId) {
require(_isApprovedOrOwner(msg.sender, tokenId), 'Not approved');
_;
}
modifier myModifier() {
// Logic to be executed before the function body
_; // Indicates the function's main logic
// Logic to be executed after the function body
}
In Solidity, isAuthorizedForToken
is a modifier. It is used to execute additional logic before or after a function. Modifiers are commonly used to implement permission checks, state validation, or other preconditions.