# Solidity-101 Basics 初階語法教學程式碼 ## 註解、Natspace format ```solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >= 0.8.4; // 單行註解 /** 多行註解 */ /** @dev 說明 @param 參數 */ function age(uint256 rings) external virtual pure returns (uint256) { return rings + 1; } ``` ## Booleans ```solidity // SPDX-License-Identifier: GPL-3.0 // solidity內1, 0不能對應true, false pragma solidity >= 0.8.4; contract Booleans { bool public isActive = true; constructor() {} } ``` ## INTEGER ```solidity // SPDX-License-Identifier: GPL-3.0 // 在真正撰寫solidity時,較少出現負數的情形,故通常都用uint即可 pragma solidity >= 0.8.4; contract Integer { uint256 public totalSupply = 250; int256 public minuseSupply = -250; constructor() {} } ``` ## String ```solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >= 0.8.4; contract String { string public Message = "Hello World"; constructor() {} } ``` ## Bytes ```solidity // SPDX-License-Identifier: GPL-3.0 // 通常使用16進制 hex pragma solidity >= 0.8.4; contract Bytes { bytes1 public hex1 = 0x01; bytes32 public hex32 = 0x0102030405060708091011121314151617181920212223242526272829303132; constructor() {} } ``` ## Address ```solidity // SPDX-License-Identifier: GPL-3.0 // 以太坊的address共160bits = 20bytes 也就是0x後面40個字元 pragma solidity >= 0.8.4; contract Storage { address public owner = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4; address public other = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2; function getOwnerBalance() public view returns (uint256) { return owner.balance; } // (2300 gas, throws error) // 現在的標準中盡量都沒有在使用transfer了 // payable()是防呆用,若沒加上就不可.transfer() & .send() function sendValueByTransfer(address to) public { payable(to).transfer(15 ether); } // (2300 gas, returns bool) // 2300 gas 是因為轉帳只是改數字,不用改變數狀態等,不用耗費這麼多gas function sendValueTo(address to) public { bool sent = payable(to).send(15 ether); require(sent, "Failed to send Ether"); } // call (forward all gas or set gas, returns bool) // 用call可以傳value or data給目標地址 // 但EOA沒有合約的data,故可以轉錢給他且不給data function sendValueByCallTo(address to) public { (bool sent, bytes memory data) = to.call{value: 15 ether}(""); require(sent, "Failed to send Ether"); } receive() external payable {} fallback() external payable {} } ``` ## Variables ```solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity >= 0.8.4; contract Variables { uint number; } ``` # 補充內容 ## bit 計算機世界中最小單位,一個 byte 是 8 個 bits 組成,每個 bit 都是由最小單位 0, 1 組成。 一個 bit 可以表示為 0 或 1,也可以等於「開或關」,也能等於數字的「零」或「一」。 ![](https://i.imgur.com/iBsMd3J.png) ![](https://i.imgur.com/MyootJK.png) ### 加解密演算法 #### ed25519 加解密訊息 ```javascript const { generateKeyPairSync, createCipheriv, createDecipheriv, randomBytes, createHash } = require('crypto') const { publicKey, privateKey } = generateKeyPairSync('ed25519', { publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', }, }) const iv = randomBytes(16).toString('hex').slice(0, 16) const key = createHash('sha256').update(publicKey).digest('base64') const message = new Buffer.from('Hello World!') const cipher = createCipheriv('aes-256-gcm', key.substr(0, 32), iv) const encrypted = cipher.update(message, 'utf8', 'hex') const encryptedFinal = cipher.final('hex') const msgCipher = encrypted + encryptedFinal const decipher = createDecipheriv('aes-256-gcm', key.substr(0, 32), iv) const msgDecipher = decipher.update(msgCipher, 'hex', 'utf8') console.log(msgDecipher.toString()) ``` #### 訊息簽章 ```javascript const { generateKeyPairSync, sign, verify, publicEncrypt, privateDecrypt } = require('crypto'); const data = require('./data.json'); const boyKeys = generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); const girlKeys = generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); const message = new Buffer.from(JSON.stringify(data)); const enc = publicEncrypt(girlKeys.publicKey, message); const signature = sign('sha256', enc, boyKeys.privateKey); const isValid = verify('sha256', enc, boyKeys.publicKey, signature); if (isValid) { console.log('valid success!', isValid) const dec = privateDecrypt(girlKeys.privateKey, enc); console.log(dec.toString()); } ```