# 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,也可以等於「開或關」,也能等於數字的「零」或「一」。


### 加解密演算法
#### 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());
}
```