# Alchemy University 学习教程，Smart Contract Basics

By [冰糖vs橙子](https://paragraph.com/@bible666) · 2023-01-08

---

估值102亿融资5.45亿的Alchemy 项目，大学每周任务逐步开始。持有大学生早期卡的伙伴们可以开始大学生活了：

官方大佬的 lens ，可以关注下：

[https://lenster.xyz/u/vitto.lens](https://lenster.xyz/u/vitto.lens)

了解更多，请关注作者：[https://twitter.com/bitc2024](https://twitter.com/bitc2024)

这一期学习Smart Contract Basics：

Solidity Syntax
---------------

### Data Types

1: Booleans

查看要求：

![](https://storage.googleapis.com/papyrus_images/ceec5c046b27d6404e7002928f9b569fe3e40dcb011cd1adfd69e7acee9d610a.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        bool public a = true;
        bool public b = false;
    }
    

点击运行。

2: Unsigned Integers

查看要求：

![](https://storage.googleapis.com/papyrus_images/0c46a707f726fb3de370ae63b817b4656469251fe3e87e4f4cd33942228b695d.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        uint8 public a = 3;
        uint16 public b = 268;
        uint256 public sum = a + b;
    }
    

点击运行。

3: Signed Integers

查看要求：

![](https://storage.googleapis.com/papyrus_images/50d324c0bd4536c93a5541c50ff2f2b94adbc38ce2cec64d21033d405dea7982.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        int8 public a = 10;
        int8 public b = -15;
        int16 public difference = a - b;
    }
    

点击运行。

4: String Literals

查看要求：

![](https://storage.googleapis.com/papyrus_images/cf3b04695b23c57a821585b789b2354e6e8be3dac15e2e5a92c5fd35bc03efe8.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        bytes32 public msg1 = "Hello World";
        string public msg2 = "ccccccccccccccccccccccccccccccccabcd";
    }
    

点击运行。

5: Enum

查看要求：

![](https://storage.googleapis.com/papyrus_images/d74499faf7b36b4698fba076d7e1d41ca113853079ba8ccfc37f8ef79e1235ef.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        enum Foods { Apple, Pizza, Bagel, Banana }
    
        Foods public food1 = Foods.Apple;
        Foods public food2 = Foods.Pizza;
        Foods public food3 = Foods.Bagel;
        Foods public food4 = Foods.Banana;
    }
    

点击运行。

Functions
---------

### Functions

1: Arguments

查看要求：

![](https://storage.googleapis.com/papyrus_images/fb5cf0f23f281d553e37b263c21fd81e5bf57bfc34163c4f9bc9986a8885415f.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        uint public x;
    
        constructor(uint _x) {
            x = _x;
        }
    }
    

点击运行。

2: Increment

查看要求：

![](https://storage.googleapis.com/papyrus_images/259c7c8913828a3f2444024b76396cfab50abb04c48dadf204bfd7e1dc34ee5e.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        uint public x;
    
        constructor(uint _x) {
            x = _x;
        }
    
        function increment() external {
            x = x + 1;
        }
    }
    

点击运行。

3: View Addition

查看要求：

![](https://storage.googleapis.com/papyrus_images/793b864b52aaad941fb397977414ee663ab1d591776c1763ef0e78a531696c0c.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        uint public x;
    
        constructor(uint _x) {
            x = _x;
        }
    
        function increment() external {
            x = x + 1;
        }
    
        function add(uint _x) external view returns(uint) {
            uint sum = x + _x;
            return sum;
        }
    }
    

点击运行。

4: Pure Double

查看要求：

![](https://storage.googleapis.com/papyrus_images/9930f47744ccc5fcfaa9a2a54ade8b118cebdc86211e9fddf99b4cc36aa01a68.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        function double(uint x) external pure returns(uint d) {
            d = x * 2;
        }
    }
    

点击运行。

5: Double Overload

查看要求：

![](https://storage.googleapis.com/papyrus_images/5e93478061a8d4dae64bd10a3d02d62d09903a104b1d1c09fc17a121217a2f17.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        function double(uint x) external pure returns(uint d) {
            d = x * 2;
        }
    
        function double(uint x, uint y) public pure returns(uint, uint) {         
                return (x*2, y*2);
        }
    }
    

点击运行。

Smart Contract Communication
----------------------------

### Contracts with ethers.js

1: Getter

查看要求：

![](https://storage.googleapis.com/papyrus_images/9e47677eb6e6e487cd092c304c4732b29e8c80adfe5f7289202a4b53f0982660.png)

输入：

    /**
     * Find the `value` stored in the contract
     *
     * @param {ethers.Contract} contract - ethers.js contract instance
     * @return {promise} a promise which resolves with the `value`
     */
    function getValue(contract) {
        let value = contract.value();
        return value;
    }
    
    module.exports = getValue;
    

点击运行。

2: Setter

查看要求：

![](https://storage.googleapis.com/papyrus_images/993d4a9b6c2b0ef17987088b89e60fbc6ccc09324068fbc06e66620437bdb8c1.png)

输入：

    /**
     * Modify the `value` stored in the contract
     *
     * @param {ethers.Contract} contract - ethers.js contract instance
     * @return {promise} a promise of transaction
     */
    function setValue(contract) {
        return contract.modify(6);
    }
    
    module.exports = setValue;
    

点击运行。

3: Transfer

查看要求：

![](https://storage.googleapis.com/papyrus_images/bf39c4b1ea484669329fff7a1608b88d4ba64317e919abccade60c9bb23b3cbc.png)

输入：

    /**
     * Transfer funds on the contract from the current signer 
     * to the friends address
     *
     * @param {ethers.Contract} contract - ethers.js contract instance
     * @param {string} friend - a string containing a hexadecimal ethereum address
     * @return {promise} a promise of the transfer transaction
     */
    function transfer(contract, friend) {
        return contract.transfer(friend, 1000);
    }
    
    module.exports = transfer;
    

点击运行。

4: Signer

查看要求：

![](https://storage.googleapis.com/papyrus_images/ad5a9fe145c14da911d941262e4a237e3899564c7f1453878db71e785c5a12f7.png)

输入：

    /**
     * Set the message on the contract using the signer passed in
     *
     * @param {ethers.Contract} contract - ethers.js contract instance
     * @param {ethers.types.Signer} signer - ethers.js signer instance
     * @return {promise} a promise of transaction modifying the `message`
     */
    function setMessage(contract, signer) {
        return contract.connect(signer).modify("abc");
    }
    
    module.exports = setMessage;
    

点击运行。

5: Deposit

查看要求：

![](https://storage.googleapis.com/papyrus_images/cb5ce017fe267795c32d6082ac027973a85722604c8d3729e01dc94704e756de.png)

输入：

    const ethers = require('ethers');
    
    /**
     * Deposit at least 1 ether into the contract 
     *
     * @param {ethers.Contract} contract - ethers.js contract instance
     * @return {promise} a promise of the deposit transaction 
     */
    function deposit(contract) {
        return contract.deposit({ value: ethers.utils.parseEther("3")});
    }
    
    module.exports = deposit;
    

点击运行。

Address Interactions
--------------------

### Sending Ether

1: Storing Owner

查看要求：

![](https://storage.googleapis.com/papyrus_images/ecf890cdb39663afd7c66ccfef166d499b4d73f9f7ac8d4ce5267d3607cb9f61.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        address public owner;
    
        constructor() {
            owner = msg.sender;
        }
    }
    

点击运行。

2: Receive Ether

查看要求：

![](https://storage.googleapis.com/papyrus_images/bd206ada8a58a725a27fb8858c183bd6e6c0ac5e5e4fee6244fede1e392f3d62.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        address public owner;
    
        constructor() {
            owner = msg.sender;
        }
    
        receive() external payable {
        }
    }
    

点击运行。

3: Tip Owner

查看要求：

![](https://storage.googleapis.com/papyrus_images/4282f9310b6d46c251c498eef09ad5001a570de7940cdcbe5b9ff790993532e5.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        address public owner;
    
        constructor() {
            owner = msg.sender;
        }
    
        receive() external payable {
        }
    
        function tip() public payable {
            (bool ret, ) = owner.call{ value: msg.value }("");
            require(ret);
        }
    }
    

点击运行。

4: Charity

查看要求：

![](https://storage.googleapis.com/papyrus_images/54a45f67b6dedec234c7b74d1797fcf893d662f86c2f1a6095bedb3bc976e87a.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        address public owner;
        address public charity;
    
        constructor(address _charity) {
            owner = msg.sender;
            charity = _charity;
        }
    
        receive() external payable {
        }
    
        function tip() public payable {
            (bool ret, ) = owner.call{ value: msg.value }("");
            require(ret);
        }
    
        function donate() public {
            (bool ret, ) = charity.call{ value: address(this).balance }("");
            require(ret);
            selfdestruct(payable(msg.sender));
        }
    }
    

点击运行。

5: Self Destruct

查看要求：

![](https://storage.googleapis.com/papyrus_images/93382d3cf05b7a68606e04d1d9600a050d6261fb524336517ae9b8b555dfefb3.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        address public owner;
        address public charity;
    
        constructor(address _charity) {
            owner = msg.sender;
            charity = _charity;
        }
    
        receive() external payable {
        }
    
        function tip() public payable {
            (bool ret, ) = owner.call{ value: msg.value }("");
            require(ret);
        }
    
        function donate() public {
            (bool ret, ) = charity.call{ value: address(this).balance }("");
            require(ret);
            selfdestruct(payable(msg.sender));
        }
    }
    

点击运行。

### Learning Revert

1: Constructor Revert

查看要求：

![](https://storage.googleapis.com/papyrus_images/d18d50a476c67ebdfd20c419ea22c10254a52b2952f1c919e5ce89be2f17b311.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract  {
        address deployer;
    
        constructor() payable {
            require(msg.value >= 1000000000000000000);
            deployer = msg.sender;
        }
    
        function withdraw() public {
            (bool ret, ) = deployer.call{ value: address(this).balance }("");
            require(ret);
        }
    }
    

点击运行。

2: Only Owner

查看要求：

![](https://storage.googleapis.com/papyrus_images/a2d1941faaa7b3be6ab624d12209243cabe47463298d5f5850b3458047e06d96.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract  {
        address deployer;
    
        constructor() payable {
            require(msg.value >= 1000000000000000000);
            deployer = msg.sender;
        }
    
        function withdraw() public {
            require(deployer == msg.sender);
            (bool ret, ) = deployer.call{ value: address(this).balance }("");
            require(ret);
        }
    }
    

点击运行。

3: Owner Modifier

查看要求：

![](https://storage.googleapis.com/papyrus_images/158888d125df2142327668b1d2275c53432e936659c2b64e683980eea03f6585.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.7.5;
    
    contract Contract {
        address owner;
        uint configA;
        uint configB;
        uint configC;
    
        constructor() {
            owner = msg.sender;
        }
    
        function setA(uint _configA) public onlyOwner {
            configA = _configA;
        }
    
        function setB(uint _configB) public onlyOwner {
            configB = _configB;
        }
    
        function setC(uint _configC) public onlyOwner {
            configC = _configC;
        }
    
        modifier onlyOwner {
            require(owner == msg.sender);
            _;
        }
    }
    

点击运行。

### Sending Data

1: Call Function

查看要求：

![](https://storage.googleapis.com/papyrus_images/977c1ab7184562103e292535b8e8ed037703ca4c33be05bce69401bb55dcab50.png)

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    interface IHero {
        function alert() external;
    }
    
    contract Sidekick {
        function sendAlert(address hero) external {
            IHero(hero).alert();
        }
    }
    

点击运行。

2: Signature

查看要求：

![](https://storage.googleapis.com/papyrus_images/ea5e08d89d57174829b4835b0a1420f675a27ac0f7a0c0c665be8a3cefa3807a.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Sidekick {
        function sendAlert(address hero) external {
            bytes4 signature = bytes4(keccak256("alert()"));
    
            (bool ret, ) = hero.call(abi.encodePacked(signature));
    
            require(ret);
        }
    }
    

点击运行。

3: With Signature

查看要求：

![](https://storage.googleapis.com/papyrus_images/1bff580bc4c44fde61b54dd59a26662c89342e7a0aee9230b6dc9f2a3fbf40b4.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Sidekick {
        function sendAlert(address hero, uint enemies, bool armed) external {
            (bool ret, ) = hero.call(
                abi.encodeWithSignature("alert(uint256,bool)", enemies, armed)
            );
    
            require(ret);
        }
    }
    

点击运行。

4: Arbitrary Alert

查看要求：

![](https://storage.googleapis.com/papyrus_images/1d392ac1606747d149f0f78d84d92cb2c828d811891c4b7f036025978810ad7e.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Sidekick {
        function relay(address hero, bytes memory data) external {
            (bool ret, ) = hero.call(data);
            require(ret);
        }
    }
    

点击运行。

5: Fallback

查看要求：

![](https://storage.googleapis.com/papyrus_images/5ec16dae993094bcb03a008721f16846f41f112ef7c3fa9fd802071c9809ef19.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Sidekick {
        function makeContact(address hero) external {
            (bool ret, ) = hero.call(abi.encodeWithSignature("fallback()"));
            require(ret);
        }
    }
    

点击运行。

Practice Solidity
-----------------

### Sum and Average

1: Sum and Average

查看要求：

![](https://storage.googleapis.com/papyrus_images/ce26c67b9b39398e07eaf363be39830bd1572327c9f991cb16d05da3530fdef2.png)

输入：

    pragma solidity ^0.8.4;
    
    contract Contract {
        function sumAndAverage(uint a, uint b, uint c, uint d) external pure returns(uint,uint) {
            uint sum = a + b + c + d;
            uint average = sum / 4;
    
            return (sum, average);
        }
    }
    

点击运行。

### Countdown

1: Countdown

查看要求：

![](https://storage.googleapis.com/papyrus_images/cf4c0c874797538e91324ec3e55fe3a4b5a8d6d539456ea481c7780c1bde738e.png)

输入：

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    contract Contract {
        uint countdown = 10;
    
        function tick() external {
            countdown--;
            if (0 == countdown) {
                selfdestruct(payable(msg.sender));
            }
        }
    }
    

点击运行。

以上，Smart Contract Basics，课程学习完成。

未完待续……

了解更多，请关注作者：[https://twitter.com/bitc2024](https://twitter.com/bitc2024)

[https://mirror.xyz/bible666.eth/X3VB59DNaNU37nTwsKOFwEUPZvEtuzbM0GJlMkK8x40](https://mirror.xyz/bible666.eth/X3VB59DNaNU37nTwsKOFwEUPZvEtuzbM0GJlMkK8x40)

---

*Originally published on [冰糖vs橙子](https://paragraph.com/@bible666/alchemy-university-smart-contract-basics)*
