# Goshen测试教程

By [cade Yu](https://paragraph.com/@cade-yu) · 2022-10-17

---

Goshen是EVM的一个layer 2通用扩展方案，目前可以进行一些简单的测试！

step 1:获取测试币
============

[https://goshen.network/](https://goshen.network/)

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

点击bridge进入跨链桥界面，之后链接你的小狐狸钱包

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

因为我们要把goreli上的eth跨链到goshen上，所以你的钱包里要有eth测试币，没有的话去这里领取：

[https://goerlifaucet.com/](https://goerlifaucet.com/)

之后点击Deposit将测试eth跨链

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

经过钱包确认并等待一段时间后，测试eth应该成功跨链了！

step 2:添加goshen网络信息
===================

上一步我们已经在goshen链得到了测试币，所以需要添加goshen测试网信息来查看

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

点击withdraw按钮，之后点击switch to gosehn testnet alpha之后，小狐狸钱包会自动添加网络信息

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

确认之后，我们就可以在小狐狸钱包上使用goshen测试网并且查看自己的余额了

step 3:更近一步，发个代币试试？
===================

打开remix

[https://remix-project.org/](https://remix-project.org/)

    //SPDX-License-Identifier: Unlicense
    pragma solidity ^0.4.24;
    
    // ----------------------------------------------------------------------------
    // Lib: Safe Math
    // ----------------------------------------------------------------------------
    contract SafeMath {
    
        function safeAdd(uint a, uint b) public pure returns (uint c) {
            c = a + b;
            require(c >= a);
        }
    
        function safeSub(uint a, uint b) public pure returns (uint c) {
            require(b <= a);
            c = a - b;
        }
    
        function safeMul(uint a, uint b) public pure returns (uint c) {
            c = a * b;
            require(a == 0 || c / a == b);
        }
    
        function safeDiv(uint a, uint b) public pure returns (uint c) {
            require(b > 0);
            c = a / b;
        }
    }
    
    
    /**
    ERC Token Standard #20 Interface
    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    */
    contract ERC20Interface {
        function totalSupply() public constant returns (uint);
        function balanceOf(address tokenOwner) public constant returns (uint balance);
        function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
        function transfer(address to, uint tokens) public returns (bool success);
        function approve(address spender, uint tokens) public returns (bool success);
        function transferFrom(address from, address to, uint tokens) public returns (bool success);
    
        event Transfer(address indexed from, address indexed to, uint tokens);
        event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
    }
    
    
    /**
    Contract function to receive approval and execute function in one call
    
    Borrowed from MiniMeToken
    */
    contract ApproveAndCallFallBack {
        function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
    }
    
    /**
    ERC20 Token, with the addition of symbol, name and decimals and assisted token transfers
    */
    contract myToken is ERC20Interface, SafeMath {
        string public symbol;
        string public  name;
        uint8 public decimals;
        uint public _totalSupply;
    
        mapping(address => uint) balances;
        mapping(address => mapping(address => uint)) allowed;
    
    
        // ------------------------------------------------------------------------
        // Constructor
        // ------------------------------------------------------------------------
        constructor() public {
            symbol = "BTC";
            name = "Bitcoin";
            decimals = 2;
            _totalSupply = 100000;
            balances[填自己的地址] = _totalSupply;
            emit Transfer(address(0), 填自己的地址, _totalSupply);
        }
    
    
        // ------------------------------------------------------------------------
        // Total supply
        // ------------------------------------------------------------------------
        function totalSupply() public constant returns (uint) {
            return _totalSupply  - balances[address(0)];
        }
    
    
        // ------------------------------------------------------------------------
        // Get the token balance for account tokenOwner
        // ------------------------------------------------------------------------
        function balanceOf(address tokenOwner) public constant returns (uint balance) {
            return balances[tokenOwner];
        }
    
    
        // ------------------------------------------------------------------------
        // Transfer the balance from token owner's account to to account
        // - Owner's account must have sufficient balance to transfer
        // - 0 value transfers are allowed
        // ------------------------------------------------------------------------
        function transfer(address to, uint tokens) public returns (bool success) {
            balances[msg.sender] = safeSub(balances[msg.sender], tokens);
            balances[to] = safeAdd(balances[to], tokens);
            emit Transfer(msg.sender, to, tokens);
            return true;
        }
    
    
        // ------------------------------------------------------------------------
        // Token owner can approve for spender to transferFrom(...) tokens
        // from the token owner's account
        //
        // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
        // recommends that there are no checks for the approval double-spend attack
        // as this should be implemented in user interfaces 
        // ------------------------------------------------------------------------
        function approve(address spender, uint tokens) public returns (bool success) {
            allowed[msg.sender][spender] = tokens;
            emit Approval(msg.sender, spender, tokens);
            return true;
        }
    
    
        // ------------------------------------------------------------------------
        // Transfer tokens from the from account to the to account
        // 
        // The calling account must already have sufficient tokens approve(...)-d
        // for spending from the from account and
        // - From account must have sufficient balance to transfer
        // - Spender must have sufficient allowance to transfer
        // - 0 value transfers are allowed
        // ------------------------------------------------------------------------
        function transferFrom(address from, address to, uint tokens) public returns (bool success) {
            balances[from] = safeSub(balances[from], tokens);
            allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
            balances[to] = safeAdd(balances[to], tokens);
            emit Transfer(from, to, tokens);
            return true;
        }
    
    
        // ------------------------------------------------------------------------
        // Returns the amount of tokens approved by the owner that can be
        // transferred to the spender's account
        // ------------------------------------------------------------------------
        function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
            return allowed[tokenOwner][spender];
        }
    
    
        // ------------------------------------------------------------------------
        // Token owner can approve for spender to transferFrom(...) tokens
        // from the token owner's account. The spender contract function
        // receiveApproval(...) is then executed
        // ------------------------------------------------------------------------
        function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
            allowed[msg.sender][spender] = tokens;
            emit Approval(msg.sender, spender, tokens);
            ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
            return true;
        }
    }
    

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

点击编译

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

之后选择部署合约上链，记住，小狐狸钱包选择goshen测试网，这样代币才能部署到goshen网络中。

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

之后找到代币合约，将它添加到小狐狸钱包中

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

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

这样我们就有了自己部署到btc代币，也许可以将代币发给其他人？谁知道呢？

twitter:@yu83612457

---

*Originally published on [cade Yu](https://paragraph.com/@cade-yu/goshen)*
