---
# System prepended metadata

title: Asset 変数の定義について
tags: [zkEVM, secret contract, Zolidity]

---

# Asset 変数の定義について

| type | from other user | primitive? | remarks |
| :--: | :--: | :--: | :--: |
| uint | ADD only | primitive|  |
| int | ADD only | primitive|deprecation |
| ufixed | ADD only | primitive|deprecation |
| fixed | ADD only | primitive|deprecation |
| bool | Nobody | primitive| |
| address | Nobody |primitive| should be recipient address or contract address |
| bytes | Nobody | primitive?||
| string | Nobody | primitive?||
| fixed-sized array | For each element, follow the type of the element |primitive?| |
| dynamiccally-sized array | PUSH only. For each element, follow the type of the element | referenced||
| set | PUSH only. For each element follow the type of the element | referenced|It is a set. It is needed for the representation of ERC721. Alike dynamically-sized array. |
| enums | Nobody |primitive| |
| function | Nobody |referenced| |
| struct | For each element, follow the type of the element | primitive(For each element, follow the type of the element)| |
| mapping | INSERT only. For each element, follow the type of the element |referenced| |


### ※ set 型について
集合を扱う型。内部的にはB木を使って表現される。次のメソッドが用意されている。
- `has(elm)` : elm が集合内にあるかを真偽値判定する
- `push(elm)` : elm を集合に加える
- `remove(elm)` : elm を集合から削除する
- `length` : 集合のサイズを返す


## Example

### zERC20

```solidity=
contract zERC20 {
    // Mapping owner address to balances of token.
    asset uint256 _balances;
    uint256 _totalSupply;
    
    ...
    
    function balanceOf(onlyContract address account) public view returns(uint256) {
        return _balances[account];
    }
    
    function transfer(address recipient, uint256 amount) public returns (bool) {
        require(recipient != address(0), "zERC20: transfer to the zero address");
        
        // fetch user state value or sender contract state if not others happened error.
        uint256 senderBalance = _balances[msg.sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        
        // output state diff `(txHash, senderOnetimeAddress, - amount)` or change contract state
        _balances[msg.sender] = senderBalance - amount;
        // output state diff `(txHash, recipientAddress, + amount)` or change contract state
        _balances[recipient] += amount;
        
        // output event (senderOnetimeAddress or sender contract address, recipienetAddress, amount);
        emit Transfer(msg.sender, recipient, amount);
    }
    
    function transferFrom(address recipient, uint256 amount) returns (bool) {
        require(recipient != address(0), "zERC20: transfer to the zero address");
        
        // fetch user state value if not state value error.
        uint256 senderBalance = _balances[tx.origin];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        
        // output state diff `(txHash, senderOnetimeAddress, - amount)`
        _balances[tx.origin] = senderBalance - amount;
        // output state diff `(txHash, recipientAddress, + amount)` or change contract state
        _balances[recipient] += amount;
        
        // output event (senderOnetimeAddress, recipienetAddress, amount);
        emit Transfer(tx.origin, recipient, amount);
    }
    ...
}
```

### zERC721
```solidity=
contract zERC721 {
    // Mapping from owner address to token ID set
    asset set _owns;

    // Mapping owner address to token count
    asset uint256 _balances;

    function transfer(
        address to,
        uint256 tokenId
    ) public returns (bool) {
        require(_owns.has(msg.sender), "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _balances[msg.sender] -= 1;
        _balances[to] += 1;
        _owns[msg.sender].remove(tokenId);
        _owns[to].push(tokenId);
        
        emit Transfer(from, to, tokenId);
    }
    
    function transferFrom(
        address to,
        uint256 tokenId
    ) public returns (bool) {
        require(_owns.has(tx.origin), "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _balances[tx.origin] -= 1;
        _balances[to] += 1;
        _owns[tx.origin].remove(tokenId);
        _owns[to].push(tokenId);
        
        emit Transfer(from, to, tokenId);        
    }
}
```

### zERC1155
```solidity=
contract zERC1155 {
    // Mapping from account to [from token ID to account balances]
    asset mapping(uint256 => uint256) _balances;

    function safeTransfer(
        address to,
        uint256 tokenId,
        uint256 amount
    ) public returns (bool) {
        require(to != address(0), "ERC1155: transfer to the zero address");

        uint256 fromBalance = _balances[msg.sender][tokenId];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        _balances[msg.sender][tokenId] = fromBalance - amount;
        _balances[to][tokenId] += amount;
        
        emit TransferSingle(from, to, tokenId, amount);
    }
    
    function transferFrom(
        address to,
        uint256 tokenId,
        uint256 amount
    ) public returns (bool) {
        require(to != address(0), "ERC1155: transfer to the zero address");

        uint256 fromBalance = _balances[tx.origin][tokenId];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        _balances[tx.origin][tokenId] = fromBalance - amount;
        _balances[to][tokenId] += amount;
        
        emit TransferSingle(from, to, tokenId, amount);
    }

    function safeBatchTransfer(
        address to,
        uint256[] tokenIds,
        uint256[] amounts
    ) public returns (bool) {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            
            uint256 fromBalance = _balances[msg.sender][tokenId];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            _balances[msg.sender][tokenId] = fromBalance - amount;
            _balances[to][tokenId] += amount;
        }
        
        emit TransferSingle(from, to, tokenId, amount);
    }
    
    function safeBatchTransferFrom(
        address to,
        uint256[] tokenIds,
        uint256[] amounts
    ) public returns (bool) {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[tx.origin][tokenId];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            _balances[tx.origin][tokenId] = fromBalance - amount;
            _balances[to][tokenId] += amount;
        }
        
        emit TransferSingle(from, to, tokenId, amount);
    }

}
```


###### tags: `zkEVM` `Zolidity` `secret contract`

