Programming Language
Pollux supports Solidity, a user-friendly smart contract development language that encompasses the following characteristics:
An object-oriented, high-level language
Statically typed
Supports inheritance, libraries, and intricate user-defined
Smart Contract Composition
A smart contract comprises both data and functions.
Data:
For any contract data, careful consideration must be given to its assignment – either to storage or memory. Modifying storage in a smart contract can be expensive, so decisions about the data's location should be made judiciously.
Storage:
Persistent data in Pollux is denoted as storage and is represented by state variables. These values are permanently stored on the blockchain. It's crucial to declare the type, allowing the contract to track the required blockchain storage during compilation.
Various variable types are available, including address, boolean, integer, fixed-point numbers, fixed-size byte arrays, dynamically-sized byte arrays, Rational and integer literals, String literals, Hexadecimal literals, and Enums.
Address:
To ensure compatibility with Ethereum, Solidity processes the data of the address by implementing the following steps on the hex-formatted address of the Pollux network account:
Remove the prefix '37' from the Pollux Hex format address.
Conduct a Mixed-case checksum on the results obtained in the previous step.
Mixed-case checksum: Applying a specific logic, certain letters in the address are capitalized, along with the remaining letters in lowercase, creating a checksum. This empowers the address with self-checking capabilities. On average, each address possesses 15 check bits. The overall probability that a randomly generated mistyped address accidentally passes a check is approximately 0.0247%.
For example, this Pollux network account P8mfGw41kXwuHZUQHDGspovq6tPwt6gMqp, the Hex format address is: 3701FBA20CB405734C6B2E704B9ED67C0B5EA74D9E , the value in solidity is:
Memory:
Data that is retained only throughout the execution of a contract function is termed Pollux variables. As these values are not permanently stored on the blockchain, their utilization comes at a considerably lower cost.
Environment variables
Alongside the variables defined within your contract, there exist specific global variables. These are predominantly employed to furnish details about the Pollux blockchain or the ongoing transaction.
Example:
Environment variables | Type | Description |
---|---|---|
block.timestamp | uint256 | Timestamp of the current block in seconds |
block.number | uint | Current block number |
block.coinbase | address | Super representative's Node address producing the current block |
msg.sender | address | Message sender (current smart contract caller) |
msg.value | uint | The amount of SUN send with message |
msg.data | bytes | complete call data |
msg.sig | bytes4 | first 4 bytes of call data (function identifier) |
now | uint | current block timestamp (block.timestamp) |
Functions
There are two categories of function calls:
Internal: These do not initiate an PVM call. Internal functions and state variables can only be accessed within the current contract or contracts derived from it.
External: These initiate an PVM call. External functions form part of the contract interface, enabling them to be invoked by other contracts and through transactions. Notably, an external function, let's say 'f,' cannot be called internally (i.e., 'f()' does not function, but 'this.f()' is valid).
Functions can further be categorized as public or private:
Public: Public functions can be invoked internally from within the contract or externally through messages.
Private: Private functions are exclusively visible within the contract where they are defined and are not accessible in derived contracts.
An example of a function for updating a state variable on a contract is provided. The parameter, a value of type string, is passed into the function named 'update_name.' Being declared public implies that anyone can access it. Notably, it is not declared as 'view,' allowing it to modify the contract state.
View functions
Functions committed to not altering the state of the contract's data, often involving query operations. Here is an illustration of such a function that retrieves account balances:
What constitutes state modification includes:
Modifying state variables through writing operations.
Emitting events.
Creating additional contracts.
Employing self-destruct.
Transmitting POX through calls.
Invoking any function lacking the 'view' or 'pure' modifier.
Utilizing low-level calls.
Employing inline assembly containing specific opcodes.
Constructor functions
Constructor functions are executed singularly during the initial deployment of the contract. Comparable to constructors in numerous class-based programming languages, these functions typically set the initial values of state variables.
Built-in functions
Apart from the variables and functions explicitly defined within your contract, there are specific built-in functions. As an illustration, consider address.send(), a function enabling the contract to transmit POX to other accounts.
Writing functions
For your function requirements, ensure the presence of:
A parameter variable and its type (if the function accepts parameters).
Declaration as public or private.
Declaration as pure, view, or payable.
Returns type (if the function yields a value).
An entire contract could resemble the following. In this example, the constructor function furnishes an initial value for the dapp_name
variable.
Events and Logs
Events enable straightforward querying of occurrences during the execution of a contract transaction. Logs, on the other hand, serve to "write" data to data structures external to smart contracts. While smart contracts cannot directly access log information, logs can offer insights into transactions and events within blocks. Upon the successful execution of a contract transaction, the smart contract can emit events and record logs on the blockchain.
Smart Contract Library
There's no necessity to create every smart contract in your project from the ground up. Numerous open-source smart contract libraries are accessible, offering reusable building blocks for your project, thus sparing you the need to reinvent the wheel.
What's in A Library
Typically, smart contract libraries offer two types of building blocks: reusable behaviors that can be incorporated into your contracts and implementations adhering to various standards.
Behaviors
In the process of crafting smart contracts, it's common to encounter the repetition of certain patterns, such as assigning an admin address for executing protected operations within a contract. Smart contract libraries often offer reusable implementations of these behaviors either as libraries or through inheritance in Solidity.
As an illustration, here's a simplified rendition of the Ownable contract from the OpenZeppelin Contracts library. This contract designates an address as the owner and includes a modifier to limit access to a method exclusively to that owner.
To integrate a building block like this into your contract, you must initially import it and then inherit from it in your own contracts. This enables you to leverage the modifier supplied by the base Ownable contract to secure your custom functions.
Another widely-used illustration is SafeMath. This library furnishes arithmetic functions equipped with overflow checks, a feature not inherently present in the language. It's considered a best practice to employ SafeMath instead of native arithmetic operations to fortify your contract against overflows, which could lead to severe consequences.
Standards
The Pollux community has established various standards known as PRCs: PRC10, PRC20, PRC721, etc. When integrating a PRC into your contracts, it's advisable to seek out standardized implementations instead of developing your own from scratch.
How to Add A Library
Refer to the documentation of the library you are incorporating for precise instructions on its integration into your project. Numerous Solidity contract libraries are available through npm, allowing for a straightforward npm installation. Pay close attention to the language version when adding a library. For example, it is not compatible to use a library designed for Solidity 0.6 if your contracts are authored in Solidity 0.5.
When to Use
Employing a smart contract library in your project offers various advantages. Foremost among them is the time saved, as these libraries provide ready-to-use building blocks that can be seamlessly integrated into your system, eliminating the need to code them from scratch. Security is a significant benefit as well. Open-source smart contract libraries often undergo rigorous scrutiny from the community, given their widespread usage in numerous projects. This continuous review process helps identify and rectify issues, making reusable contract libraries more reliable than application code. Some libraries even undergo external audits to enhance their security measures.
Nevertheless, the use of smart contract libraries comes with the risk of incorporating unfamiliar code into your project. Without a comprehensive understanding of a contract's functionality, there's a possibility of introducing unexpected issues into your system. Always ensure to thoroughly read the documentation of the imported code and review the code itself before integrating it into your project.
Lastly, when deciding whether to include a library, consider its overall adoption within the community. Libraries with widespread usage benefit from a larger community, increasing the number of eyes scrutinizing them for potential issues. When building with smart contracts, prioritize security as the key focus!
Last updated