diff --git a/docs/Computer Science/Blockchain/ERC.md b/docs/Computer Science/Blockchain/ERC.md new file mode 100644 index 0000000..49ecdeb --- /dev/null +++ b/docs/Computer Science/Blockchain/ERC.md @@ -0,0 +1,223 @@ +# ERC Standards + +!!! Info + 参考: + + - [openzeppelin 的 ERC 实现]() + - [xg 有关 ERC 的笔记](https://note.tonycrane.cc/ctf/blockchain/eth/erc/) + +## ERC-20 + +## ERC-721 + +### Events + +- `event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);` + - Emitted when `tokenId` token is transferred from `from` to `to`. +- `event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);` + - Emitted when `owner` enables `approved` to manage the `tokenId` token. +- `event ApprovalForAll(address indexed owner, address indexed operator, bool approved);` + - Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + +### Approve + +- `function approve(address to, uint256 tokenId) public virtual;` + - 作用:授权 `tokenId` 给 `to`。 + - 细节:见 `_approve`,只有在需要发出事件(`emitEvent` 为真)或者授权者不为 0 时才读取所有者,这时候会检查代币拥有者是否是授权者、`auth` 是否被代币的拥有者授权,这两个条件均不满足就会抛出异常。我们经常使用的 `approve` 函数就默认了 `emitEvent` 为真,这时候会仔细检查授权情况。在最后将 `_tokenApprovals[tokenId]` 设置为 `to`。 + - 实现: + ```solidity + function approve(address to, uint256 tokenId) public virtual { + _approve(to, tokenId, _msgSender()); + } + + function _approve(address to, uint256 tokenId, address auth) internal { + _approve(to, tokenId, auth, true); + } + + function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { + // Avoid reading the owner unless necessary + if (emitEvent || auth != address(0)) { + address owner = _requireOwned(tokenId); + // We do not use _isAuthorized because single-token approvals should not be able to call approve + if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { + revert ERC721InvalidApprover(auth); + } + if (emitEvent) { + emit Approval(owner, to, tokenId); + } + } + _tokenApprovals[tokenId] = to; + } + ``` +- `function setApprovalForAll(address operator, bool approved) public virtual;` + - 实现: + ```solidity + function setApprovalForAll(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { + if (operator == address(0)) { + revert ERC721InvalidOperator(operator); + } + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + ``` + +### Inquire + +- `function balanceOf(address owner) public view virtual returns (uint256);` + +- `function ownerOf(uint256 tokenId) public view virtual returns (address);` + +- `function getApproved(uint256 tokenId) public view virtual returns (address);` + - 作用:查询 tokenId 的授权者,也就是返回 `_tokenApprovals[tokenId]`,同时要求该代币存在(拥有者不为 0)。 + - 实现: + ```solidity + function getApproved(uint256 tokenId) public view virtual returns (address) { + _requireOwned(tokenId); + return _getApproved(tokenId); + } + + function _getApproved(uint256 tokenId) internal view virtual returns (address) { + return _tokenApprovals[tokenId]; + } + ``` +- `function isApprovedForAll(address owner, address operator) public view virtual returns (bool);` + - 实现: + ```solidity + function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { + return _operatorApprovals[owner][operator]; + } + ``` + + +### Check + +- `function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool);` + - 作用:检查 `spender` 是否有权限操作 `tokenId`,但是不抛出异常。 + - 细节:要求 `spender` 不为 0,同时需要下面三个要求满足其一: + - `owner` 与 `spender` 相同,拥有者自然有权操纵代币; + - `owner` 授权给 `spender`,全局授权,`spender` 可以操纵 `owner` 的所有代币; + - `tokenId` 的授权者是 `spender`。 + - 实现: + ```solidity + function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { + return + spender != address(0) && + (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); + } + ``` +- `function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual;` + - 作用:检查 `spender` 是否有权限操作 `tokenId`,如果没有就抛出异常。 + - 细节:首先调用 `_isAuthorized` 检查权限,如果没有权限就抛出异常,异常分为两种情况: + - `owner` 为 0,代币不存在,抛出 `ERC721NonexistentToken` 异常; + - `owner` 为 0,代币存在,但是 `spender` 没有权限, 抛出 `ERC721InsufficientApproval` 异常。 + - 实现: + ```solidity + function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { + if (!_isAuthorized(owner, spender, tokenId)) { + if (owner == address(0)) { + revert ERC721NonexistentToken(tokenId); + } else { + revert ERC721InsufficientApproval(spender, tokenId); + } + } + } + ``` +- `function _update(address to, uint256 tokenId, address auth) internal virtual returns (address);` + - 实现: + ```solidity + function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { + address from = _ownerOf(tokenId); + + // Perform (optional) operator check + if (auth != address(0)) { + _checkAuthorized(from, auth, tokenId); + } + + // Execute the update + if (from != address(0)) { + // Clear approval. No need to re-authorize or emit the Approval event + _approve(address(0), tokenId, address(0), false); + + unchecked { + _balances[from] -= 1; + } + } + + if (to != address(0)) { + unchecked { + _balances[to] += 1; + } + } + + _owners[tokenId] = to; + + emit Transfer(from, to, tokenId); + + return from; + } + ``` +- `function _requireOwned(uint256 tokenId) internal view virtual returns (address);` + - 作用:检查 tokenId 是否存在,如果不存在(也就是拥有者为地址 0)就抛出异常。 + - 实现: + ```solidity + function _requireOwned(uint256 tokenId) internal view returns (address) { + address owner = _ownerOf(tokenId); + if (owner == address(0)) { + revert ERC721NonexistentToken(tokenId); + } + return owner; + } + ``` + +### Transfer + +- `function transferFrom(address from, address to, uint256 tokenId) public virtual;` + - 实现: + ```solidity + function transferFrom(address from, address to, uint256 tokenId) public virtual { + if (to == address(0)) { + revert ERC721InvalidReceiver(address(0)); + } + // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists + // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. + address previousOwner = _update(to, tokenId, _msgSender()); + if (previousOwner != from) { + revert ERC721IncorrectOwner(from, tokenId, previousOwner); + } + } + ``` +- `function safeTransferFrom(address from, address to, uint256 tokenId) public;` + - 实现: + ```solidity + function safeTransferFrom(address from, address to, uint256 tokenId) public { + safeTransferFrom(from, to, tokenId, ""); + } + + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { + transferFrom(from, to, tokenId); + _checkOnERC721Received(from, to, tokenId, data); + } + + function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private { + if (to.code.length > 0) { + try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { + if (retval != IERC721Receiver.onERC721Received.selector) { + revert ERC721InvalidReceiver(to); + } + } catch (bytes memory reason) { + if (reason.length == 0) { + revert ERC721InvalidReceiver(to); + } else { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, reason), mload(reason)) + } + } + } + } + } + ``` \ No newline at end of file diff --git a/docs/Computer Science/Blockchain/Ethereum.md b/docs/Computer Science/Blockchain/Ethereum.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Computer Science/Blockchain/Solidity.md b/docs/Computer Science/Blockchain/Solidity.md new file mode 100644 index 0000000..d0ceb6a --- /dev/null +++ b/docs/Computer Science/Blockchain/Solidity.md @@ -0,0 +1,193 @@ +# Solidity + +!!! Info "What is Solidity?" + Solidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs that govern the behavior of accounts within the Ethereum state. + + Solidity is a curly-bracket language designed to target the Ethereum Virtual Machine (EVM). It is influenced by C++, Python, and JavaScript. You can find more details about which languages Solidity has been inspired by in the language influences section. + + Solidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features. + + 说白了,Solidity 其实就是一种智能合约编程语言,特别是以太坊的官方语言。 + + 参考: + + - [Solidity - Solidity 0.8.26 documentation](https://docs.soliditylang.org/en/v0.8.26/) + - [xg 的 Solidity 笔记](https://note.tonycrane.cc/ctf/blockchain/eth/solidity/) + +## 1 结构 + +## 2 数据类型 + +Solidity 是一个静态类型语言,并且没有 null 或 undefined 类型,取而代之的是默认值:每个新建的变量依据其类型都会有一个默认值。 + +### 2.1 数值类型 + +1. 布尔类型/Boolean: + + - 取值:`true` 与 `false`; + - 支持运算:`||`、`&&`、`!`、`==`、`!=`。 + +2. 整数类型/Integer: + +3. 定点数类型/Fixed Point Numbers: + +4. 地址类型/Address: + +5. 定长字节数组/Fixed-size Byte Arrays: + +6. 枚举类型/Enum: + +7. 用户自定义类型/User-defined Value Types: + +8. 合约类型/Contract: + +### 2.2 函数类型 + +其实函数类型也隶属于数值类型 QAQ,但是单提出来了。 + +### 2.3 引用类型 + +### 2.4 映射类型 + +映射/Mapping 的语法是 `#!solidity mapping(KeyType KeyName? => ValueType ValueName?) VariableName`,其中 `KeyName` 和 `ValueName` 可以省略。键的类型只能是内置类型,比如 bytes、address、contact、enum 等,但是值的类型就可以是任意类型了,用户自定义类型也可以。 + +给映射新增的键值对的语法为 `_Var[_Key] = _Value`,其中 `_Var` 是映射变量名,`_Key` 和 `_Value` 对应新增的键值对。 + +映射类型**不存储键**,使用 `keccak256(abi.encodePacked(key, slot))` 当成 offset 存取 value,`slot` 是映射变量定义所在的插槽位置。因而映射类型没有长度属性。 + +映射中未初始化的值会被初始化为其类型的默认值。 + +映射的存储位置必须是 `storage`,因此可以用于合约的状态变量,函数中的 `storage` 变量,和 library 函数的参数。不能用于 `public` 函数的参数或返回结果中,因为 `mapping` 记录的是一种关系(键值对)。 + +如果映射声明为 `public`,那么 solidity 会自动给你创建一个 `getter` 函数,可以通过 `Key` 来查询对应的 `Value`,比如文档中的例子: + +```solidity +contract MappingExample { + mapping(address addr => uint balance) public balances; + + function update(uint newBalance) public { + balances[msg.sender] = newBalance; + } +} + +contract MappingUser { + function f() public returns (uint) { + MappingExample m = new MappingExample(); + m.update(100); + return m.balances(address(this)); + } +} +``` + +尽管一般的映射没法遍历,因为没法枚举键,但是我们可以建立一个在映射之上的数据结构,这样间接对映射进行遍历,就实现了 Iterable Mapping,下面是实现: + +??? Info "Implementation of Iterable Mapping" + + ```solidity + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.8; + + struct IndexValue { uint keyIndex; uint value; } + struct KeyFlag { uint key; bool deleted; } + + struct itmap { + mapping(uint => IndexValue) data; + KeyFlag[] keys; + uint size; + } + + type Iterator is uint; + + library IterableMapping { + function insert(itmap storage self, uint key, uint value) internal returns (bool replaced) { + uint keyIndex = self.data[key].keyIndex; + self.data[key].value = value; + if (keyIndex > 0) + return true; + else { + keyIndex = self.keys.length; + self.keys.push(); + self.data[key].keyIndex = keyIndex + 1; + self.keys[keyIndex].key = key; + self.size++; + return false; + } + } + + function remove(itmap storage self, uint key) internal returns (bool success) { + uint keyIndex = self.data[key].keyIndex; + if (keyIndex == 0) + return false; + delete self.data[key]; + self.keys[keyIndex - 1].deleted = true; + self.size --; + } + + function contains(itmap storage self, uint key) internal view returns (bool) { + return self.data[key].keyIndex > 0; + } + + function iterateStart(itmap storage self) internal view returns (Iterator) { + return iteratorSkipDeleted(self, 0); + } + + function iterateValid(itmap storage self, Iterator iterator) internal view returns (bool) { + return Iterator.unwrap(iterator) < self.keys.length; + } + + function iterateNext(itmap storage self, Iterator iterator) internal view returns (Iterator) { + return iteratorSkipDeleted(self, Iterator.unwrap(iterator) + 1); + } + + function iterateGet(itmap storage self, Iterator iterator) internal view returns (uint key, uint value) { + uint keyIndex = Iterator.unwrap(iterator); + key = self.keys[keyIndex].key; + value = self.data[key].value; + } + + function iteratorSkipDeleted(itmap storage self, uint keyIndex) private view returns (Iterator) { + while (keyIndex < self.keys.length && self.keys[keyIndex].deleted) + keyIndex++; + return Iterator.wrap(keyIndex); + } + } + + // How to use it + contract User { + // Just a struct holding our data. + itmap data; + // Apply library functions to the data type. + using IterableMapping for itmap; + + // Insert something + function insert(uint k, uint v) public returns (uint size) { + // This calls IterableMapping.insert(data, k, v) + data.insert(k, v); + // We can still access members of the struct, + // but we should take care not to mess with them. + return data.size; + } + + // Computes the sum of all stored data. + function sum() public view returns (uint s) { + for ( + Iterator i = data.iterateStart(); + data.iterateValid(i); + i = data.iterateNext(i) + ) { + (, uint value) = data.iterateGet(i); + s += value; + } + } + } + ``` + + +### 2.5 运算符 + +## 3 单位与变量 + +## 4 表达式与控制流 + + +## 5 合约 diff --git a/docs/Computer Science/CTF/DNS.md b/docs/Computer Science/CTF/DNS.md new file mode 100644 index 0000000..843a881 --- /dev/null +++ b/docs/Computer Science/CTF/DNS.md @@ -0,0 +1,87 @@ +# DNS Transport Protocol + +## 报文格式 + +DNS 报文分为**请求**和**应答**两种,这两种报文结构类似,大致有五部分: + +- 报文头/Header:长 12 字节,描述报文类型,以及下面四个小节的情况; +- 问题节/Question:保存查询信息,长度不定; +- 答案节/Answer:保存查询结果,长度不定; +- 授权信息节/Authority:保存授权信息,长度不定; +- 附加信息节/Additional:保存附加信息,长度不定。 + +### 报文头/Header + +报文头的长度是固定的,一共是 12 个字节,包含了报文的基本信息: + +- **标识/Identifier**:一个 16 位 2 字节的 ID,在应答之中原样返回,以此匹配请求与应答; +- **标志/Flags**:一些标志位,一共 16 位 2 字节,从低到高依次为: + - **QR**:占 1 位,标识报文类型,0 为请求,1 为应答,DNS 回复时将其置为 1; + - **Opcode**:占 4 位,定义查询和应答的类型。0 表示标准查询,1 表示反向查询(由 IP 地址获得主机域名),2 表示请求服务器状态; + - **AA/授权应答/Authoritative Answer**:占 1 位,这个比特位在应答的时候才有意义,指出给出应答的服务器是否为查询域名的授权解析服务器,0 表示结果不是由域名的权威服务器返回的,因为查询对象是本地的 DNS 缓存服务器,1 表示结果是由域名的权威服务器返回的; + - **TC/截断/TrunCation**:占 1 位,用来指出是否报文比允许的长度还要长,进而导致被截断; + - **RD/期望递归/Recursion Desired**:占 1 位,在请求的时候设置,并且要在应答时返回,如果该位为 1,服务器就必须处理这个请求,如果服务器没有授权回答,它必须替客户端请求其他 DNS 服务器,这也是所谓的 **递归查询**;该位为 0 时,如果服务器没有授权回答,它就返回一个能够处理该查询的服务器列表给客户端,由客户端自己进行 **迭代查询**; + - **RA/支持递归/Recursion Available**:占 1 位,如果服务器支持递归查询,就会在应答中设置该位,以告知客户端; + - **Z/ZERO**:占 3 位,未用保留值,值都为 0; + - **RCODE**:占 4 位,返回码,表示请求结果,通常为 0/没有差错 和 3/名字差错,当出现差错的时候,这个差错由权威服务器返回,表示待查询的域名不存在; + - **QDCOUNT**:占 16 位 2 字节,表示一个 16 位无符号整数,指明报文请求段中的问题记录数,就是要查询的域名,一般为 1; + - **ANCOUNT**:占 16 位 2 字节,表示一个 16 位无符号整数,指明报文回答段中的回答记录数,查询报文中该字段为 0; + - **NSCOUNT**:占 16 位 2 字节,表示一个 16 位无符号整数,指明报文授权段中的授权记录数,查询报文中该字段为 0; + - **ARCOUNT**:占 16 位 2 字节,表示一个 16 位无符号整数,指明报文附加段中的附加记录数,查询报文中该字段为 0。 + +### 问题节/Question + +查询包只有报文头和问题节两部分,报文头的 QDCOUNT 指明报文含有多少个查询结构,每个查询结构都由下面的字段组成: + +- QNAME:查询的域名,长度不固定,ascii 编码,域名内以 `.` 切分,具体分隔方法(DNS 标准名称表示法)如下: + - 比如查询 `example.com.`,由于长度不固定,加之以 `.` 进行了切分,切分下来的部分都叫做 label,所以我们在每个 label 前面都加上一个**前导字节**,表示该 label 的字节长度,所以例子的域名就变成 `\x07example\x03com\x00`,这里最后的空字符串代表根域。 + - 但是域名表示还有相应的域名压缩方法,对于这种不需要域名压缩的一般的域名,前导字节的高两位必须需要为 `0`,后边表示该 label 的长度,由此可见,每一级域名的长度**理论上**最多可以达到 63/`0x3f` 个字符。 +- QTYPE:查询的类型,长 16 位 2 字节,常见的有: + - A 记录类型,值为 1,查询主机 IP 地址; + - NS 记录类型,值为 2,查询权威名称服务器; + - CNAME 记录类型,值为 5,查询 CNAME 别名; + - MX 记录类型,值为 15/`0x0f`,邮件交换; + - TXT 记录类型,值为 16/`0x10`,文本记录; +- QCLASS:查询的类,长 16 位 2 字节,常见的有: + - IN 类,值为 1,Internet 类; + - CH 类,值为 3,Chaos 类(这是啥); + - HS 类,值为 4,Hesiod 类(这是啥); + - `*` 类,值为 255/`0xff`,所有类。 + +### 资源记录格式/Resource Record/RR + +答案节、授权信息节与附加信息节这些字段都应该使用**资源记录/RR** 格式,分为 6 个部分: + +- NAME:回复查询的域名,长度不固定,跟查询域名对应,这里为了减少包长度,一般进行**域名压缩**,下面会讲; +- TYPE:占 16 位 2 字节,跟上面的 QTYPE 意思基本一样。 +- CLASS:占 16 位 2 字节,跟上面的 QCLASS 基本一样。 +- TTL:占 32 位,表示一个 32 位无符号整数,标识资源记录可以缓存的时间,单位是秒。0 代表只能被传输,但是不能被缓存。 +- RDLENGTH:占 16 位 2 字节,表示一个 16 位无符号整数,标识 RDATA 的长度。 +- RDATA:不定长字符串来表示记录,格式根 TYPE 和 CLASS 有关。比如:TYPE 是 A,CLASS 是 IN,那么 RDATA 就是一个 4 个字节的 ARPA 网络地址。 + +但是问题节与答案节等的 NAME 部分会有很大的重叠,所以我们会进行**域名压缩**,这样可以减少包的长度,节约报文空间:当域名在报文之中第二次出现的时候,只用两个字节来保存。第一个字节的最高两位都是 `1`,余下部分和第二个字节组合在一起,表示域名第一次出现时在报文内的偏移量/Offset,可以叫它**压缩指针**,通过这个压缩指针就可以找到对应的域名,真实的域名在整个数据包的 Offset 处。由于一般的报文头的域名位置还是很靠前的,所以我们一般会见到 `0x0Cxx` 这样的压缩指针。 + +一个域名 NAME 里边最多只能有一个压缩指针,换句话说,一个域名只有可能有下面三种形式: + +- 一堆 label 后边跟着一个 `0x00` 表示的根域(也表示了结束); +- 一个压缩指针; +- 一堆 label 序列,后边跟一个压缩指针。 + +有时候我们甚至还要在一个字段里边表示一个电子邮件,位了方便复用,我们将电子邮件里边的 `@` 替换成一个 `.`,这样编码就都一样了。 + +## dnscat Protocol + + + + + + \ No newline at end of file diff --git a/docs/Computer Science/Programming Language/C++/Object Oriented Programming.md b/docs/Computer Science/Programming Language/C++/OOP.md similarity index 100% rename from docs/Computer Science/Programming Language/C++/Object Oriented Programming.md rename to docs/Computer Science/Programming Language/C++/OOP.md diff --git a/docs/Computer Science/Programming Language/Python/03IO.md b/docs/Computer Science/Programming Language/Python/IO.md similarity index 100% rename from docs/Computer Science/Programming Language/Python/03IO.md rename to docs/Computer Science/Programming Language/Python/IO.md diff --git a/docs/Computer Science/Programming Language/Python/OOP.md b/docs/Computer Science/Programming Language/Python/OOP.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Computer Science/Programming Language/Python/01VariableAndTypes.md b/docs/Computer Science/Programming Language/Python/VAT.md similarity index 100% rename from docs/Computer Science/Programming Language/Python/01VariableAndTypes.md rename to docs/Computer Science/Programming Language/Python/VAT.md diff --git a/docs/css/MonaspaceArgon-Regular.woff b/docs/css/MonaspaceArgon-Regular.woff new file mode 100644 index 0000000..adcd7ba Binary files /dev/null and b/docs/css/MonaspaceArgon-Regular.woff differ diff --git a/docs/css/custom.css b/docs/css/custom.css index b024564..0f5f069 100644 --- a/docs/css/custom.css +++ b/docs/css/custom.css @@ -3,15 +3,23 @@ src: url("MonaspaceArgon-Light.woff"); } + @font-face { + font-family: "Monaspace Argon"; + src: url("MonaspaceArgon-Regular.woff"); + } + :root { - --md-text-font: "Monaspace Argon Light", "LXGW WenKai Screen"; - --md-code-font: 'Monaspace Argon Light', "JetBrains Mono", 'LXGW WenKai Screen'; + --md-text-font: "LXGW WenKai Screen"; + --md-code-font: 'Monaspace Argon', 'LXGW WenKai Screen'; --md-code-font-size: .075em; } + + /* "JetBrains mono", "Monaspace Argon Light", */ p code, li code { - font-family: 'Monaspace Argon Light', 'LXGW WenKai Screen'; + font-family: 'Monaspace Argon Light', "Monaspace Argon", 'LXGW WenKai Screen'; src: url(https://v1ceversaa.github.io/docs/css/MonaspaceArgon-Light.woff) format("woff"); + src: url(https://v1ceversaa.github.io/docs/css/MonaspaceArgon-Regular.woff) format("woff"); } .md-typeset code, .md-typeset kbd, diff --git a/mkdocs.yml b/mkdocs.yml index dbc7a1b..c276985 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -138,9 +138,15 @@ nav: - C++: - Computer Science/Programming Language/C++/C++.md - Basic Syntax: Computer Science/Programming Language/C++/Basic Syntax.md + - Object Oriented Programming: Computer Science/Programming Language/C++/OOP.md - Standard Library: Computer Science/Programming Language/C++/Standard Library.md - Python: - Computer Science/Programming Language/Python/Python.md + - Variable and Types: Computer Science/Programming Language/Python/VAT.md + - Input and Output: Computer Science/Programming Language/Python/IO.md + - Object Oriented Programming: Computer Science/Programming Language/Python/OOP.md + - Library: Computer Science/Programming Language/Python/Library.md + - Pwntools: Computer Science/Programming Language/Python/Pwntools.md - Java: Computer Science/Programming Language/Java.md - Rust: - Computer Science/Programming Language/Rust/Rust.md @@ -155,6 +161,12 @@ nav: - Graph: Computer Science/Algorithm/04 Graph.md - Sorting: Computer Science/Algorithm/05 Sorting.md - Hash: Computer Science/Algorithm/06 Hash.md + - Blockchain: + - Computer Science/Blockchain/Blockchain.md + - Ethereum: + - Computer Science/Blockchain/Ethereum.md + - Solidity: Computer Science/Blockchain/Solidity.md + - ERC Standard: Computer Science/Blockchain/ERC.md - Web: - Computer Science/Web/index.md - CSS: Computer Science/Web/CSS.md @@ -163,6 +175,8 @@ nav: - Javascript: Computer Science/Web/Javascript/Javascript.md - Vue: Computer Science/Web/Javascript/Vue.md - YAML: Computer Science/Web/YAML.md + - CTF: + - DNS Protocol: Computer Science/CTF/DNS.md - System: - System/index.md @@ -243,6 +257,7 @@ nav: - The Western Heritage: - Reading/The Western Heritage/The Western Heritage.md - Chapter 0: Reading/The Western Heritage/Chapter00.md + - Chapter 1: Reading/The Western Heritage/Chapter01.md - Taking Sides: - Reading/Taking Sides/index.md - Sustainability: Reading/Taking Sides/Sustainability.md