跨平臺(tái)數(shù)據(jù)類型指南
由于 Solidity 和 JavaScript/TypeScript 的設(shè)計(jì)目標(biāo)和應(yīng)用場(chǎng)景不同,某些類型的對(duì)應(yīng)關(guān)系可能不完全直接,需要進(jìn)行一些轉(zhuǎn)換或使用特定的庫。
| Solidity 類型 | Dart 類型 | JavaScript/TypeScript 類型 | 備注 |
|---|---|---|---|
bool |
bool |
boolean |
直接對(duì)應(yīng)。 |
uint8, uint16, uint32, uint64, uint256
|
BigInt |
number (如果數(shù)值較小) / string (推薦) / BigInt (ES2020+) |
JavaScript 的 number 類型只能安全地表示 -2^53 到 2^53 之間的整數(shù)。對(duì)于 Solidity 中的大整數(shù),推薦使用字符串表示,或者使用 ES2020 引入的 BigInt 類型。需要注意的是,BigInt 在一些舊版本的瀏覽器中可能不支持。 |
int8, int16, int32, int64, int256
|
BigInt |
number (如果數(shù)值較小) / string (推薦) / BigInt (ES2020+) |
同樣,對(duì)于 Solidity 中的大整數(shù),推薦使用字符串表示,或者使用 ES2020 引入的 BigInt 類型。 |
address |
EthereumAddress (來自 web3dart 包) |
string |
以太坊地址通常表示為 16 進(jìn)制字符串??梢允褂?ethers 或 web3.js 等庫提供的工具函數(shù)來驗(yàn)證地址的有效性。 |
string |
String |
string |
直接對(duì)應(yīng)。 |
bytes1, bytes2, ..., bytes32
|
Uint8List |
string / number[]
|
可以使用 16 進(jìn)制字符串表示,或者使用 Uint8Array (number[]) 表示字節(jié)數(shù)組。 |
bytes |
Uint8List |
string / number[]
|
可以使用 16 進(jìn)制字符串表示,或者使用 Uint8Array (number[]) 表示字節(jié)數(shù)組。 |
fixed, ufixed
|
double (不推薦), 或者使用自定義類型和 BigInt
|
number / string / 自定義類型 |
JavaScript 沒有直接對(duì)應(yīng)的定點(diǎn)數(shù)類型??梢允褂?number 類型近似表示,但會(huì)有精度損失。推薦使用字符串表示,或者使用第三方庫來處理定點(diǎn)數(shù)。 |
enum |
enum (Dart) |
string (推薦) / number / enum (TypeScript) |
在 TypeScript 中,可以使用 enum 關(guān)鍵字定義枚舉類型。如果需要在 JavaScript 中使用,可以使用字符串或數(shù)字來表示枚舉值。 使用字符串可以提高代碼的可讀性。 |
mapping |
不直接對(duì)應(yīng) | JavaScript 對(duì)象 ({ [key: string]: value }) / Map
|
Solidity 中的 mapping 類似于 JavaScript 中的對(duì)象或 Map。你需要根據(jù) key 來讀取 mapping 的值。 在與智能合約交互時(shí),通常需要編寫合約函數(shù)來讀取 mapping 的值。 |
array (fixed size) |
List<Type> |
Type[] |
例如 uint256[3] 對(duì)應(yīng) string[] (如果使用字符串表示大整數(shù))。 |
array (dynamic size) |
List<Type> |
Type[] |
例如 uint256[] 對(duì)應(yīng) string[] (如果使用字符串表示大整數(shù))。 |
注意:
- 在 JavaScript/TypeScript 中處理 Solidity 的數(shù)據(jù)類型時(shí),需要考慮類型轉(zhuǎn)換和數(shù)據(jù)格式化的問題。
- 可以使用
ethers或web3.js等庫來簡(jiǎn)化與智能合約的交互。 - 對(duì)于復(fù)雜的數(shù)據(jù)結(jié)構(gòu),可能需要自定義類型或使用第三方庫來處理。
-
BigInt是 ES2020 引入的新特性,需要確保你的運(yùn)行環(huán)境支持。
// 案例用 Solidity 0.8+ 版本編寫
// = 1.智能合約基礎(chǔ)結(jié)構(gòu) =
contract SimpleContract {
// 狀態(tài)變量(永久存儲(chǔ)在鏈上)
address public owner;
uint256 public count;
// 構(gòu)造函數(shù)(只在部署時(shí)執(zhí)行一次)
constructor() {
owner = msg.sender;
count = 0;
}
}
// = 2.數(shù)據(jù)類型與變量操作 =
contract DataTypes {
// 值類型
uint8 public smallNumber = 255; // 無符號(hào)8位整數(shù)
address public myAddress = 0x123...; // 以太坊地址
// 引用類型
struct Person {
string name;
uint age;
}
Person[] public people; // 動(dòng)態(tài)結(jié)構(gòu)體數(shù)組
// 映射類型
mapping(address => uint) public balances;
}
// = 3.函數(shù)與可見性 =
contract Functions {
uint private secretNumber = 42; // 私有變量
// public: 外部和內(nèi)部均可調(diào)用
function add(uint a, uint b) public pure returns(uint) {
return a + b;
}
// external: 只能從外部調(diào)用
function deposit() external payable {
require(msg.value > 0, "Need ETH");
}
}
// = 4.事件與日志 =
contract EventDemo {
// 聲明轉(zhuǎn)賬事件(鏈下可監(jiān)聽)
event Transfer(address indexed from, address to, uint amount);
function sendCoin(address to, uint amount) public {
emit Transfer(msg.sender, to, amount); // 觸發(fā)事件
}
}
// = 5.錯(cuò)誤處理 =
contract ErrorHandling {
function withdraw(uint amount) public {
require(amount <= 100, "Exceed max limit"); // 條件檢查
if (amount == 0) {
revert("Amount cannot be zero"); // 主動(dòng)回滾
}
// ...邏輯代碼
}
}
// = 6.繼承與接口 =
interface IERC20 {
function transfer(address to, uint amount) external;
}
contract MyToken is IERC20 { // 實(shí)現(xiàn)接口
function transfer(address to, uint amount) external override {
// 轉(zhuǎn)賬邏輯...
}
}
// = 7.支付處理 =
contract PaymentDemo {
// payable修飾符允許接收ETH
function buyItem() external payable {
require(msg.value == 1 ether, "Need 1 ETH");
}
// 提取合約余額
function withdraw() external {
payable(msg.sender).transfer(address(this).balance);
}
}
// = 8.存儲(chǔ)位置示例 =
contract StorageExample {
struct User {
string name;
uint score;
}
User[] public users; // storage類型
function addUser(string memory name) public { // memory臨時(shí)存儲(chǔ)
users.push(User(name, 0));
}
}
// = 9.安全模式示例 =
contract ReentrancyGuard {
// 防重入鎖
bool private locked;
modifier nonReentrant() {
require(!locked, "Operation locked");
locked = true;
_;
locked = false;
}
function safeWithdraw() public nonReentrant {
// 提款安全邏輯
}
}