【Solidity】复杂数据结构

Array

contract Demo {
    // 固定大小的数组
    uint[3] public fixedArray; // [0, 0, 0]
    uint[] public arr = new uint[](3); // [0, 0, 0]

    // 动态大小的数组
    uint[] public dynamicArray; // []
}

操作动态大小的数组:

// 获取数组长度
function getLength() public view returns (uint) {
    return dynamicArray.length;
}

// 获取指定元素
function get(uint _index) public view returns (uint) {
    return dynamicArray[_index];
}

// 添加元素
function push(uint _value) public {
    dynamicArray.push(_value);
}

// 更新指定元素
function set(uint _index, uint _value) public {
    dynamicArray[_index] = _value;
}

// 删除指定元素; eg: [1, 2, 3] - [1, 0, 3]
function deleteByIndex(uint _index) public {
    delete dynamicArray[_index]; // 注意: 这里是将该元素重置为默认值了, 不会改变数组的长度
}

// 删除最后一个元素; eg: [1, 2, 3] - [1, 2]
function pop() public {
    dynamicArray.pop();
}

// 删除指定元素; eg: [1, 2, 3] - [1, 3]
function remove(uint _index) public {
    for (uint i = _index; i < dynamicArray.length - 1; i++) {
        dynamicArray[i] = dynamicArray[i + 1];
    }
    dynamicArray.pop();
}

// 删除所有元素; eg: [1, 2, 3] - []
function clear() public {
    delete dynamicArray; // 注意: 这里是将数组重置为空数组了, 数组长度变为 0
}

操作固定大小的数组:

// 获取数组长度
function getLength() public view returns (uint) {
    return fixedArray.length;
}

// 获取指定元素
function get(uint _index) public view returns (uint) {
    return fixedArray[_index];
}

// 更新指定元素
function set(uint _index, uint _value) public {
    fixedArray[_index] = _value;
}

// 删除指定元素; eg: [1, 2, 3] - [1, 0, 3]
function deleteByIndex(uint _index) public {
    delete fixedArray[_index]; // 注意: 这里是将该元素重置为默认值了, 不会改变数组的长度
}

// 删除所有元素; eg: [1, 2, 3] - []
function clear() public {
    delete fixedArray; // 注意: 这里是将所有元素重置为默认值了, 不会改变数组的长度
}

在内存中创建数组:

contract Demo {
    function createArray(uint256 size) public pure returns (uint256[] memory) {
        uint256[] memory arr = new uint256[](size);
        for (uint256 i = 0; i < size; i++) {
            arr[i] = i;
        }
        return arr;
    }
}

demo - 接受一个整数数组和一个索引作为参数,移除索引指定的元素并返回新数组:

function removeAtIndex(
    uint[] memory arr,
    uint index
) public pure returns (uint[] memory) {
    uint[] memory newArr = new uint[](arr.length - 1);

    for (uint i = 0; i < arr.length; i++) {
        if (i < index) {
            newArr[i] = arr[i];
        } else if (i > index) {
            newArr[i - 1] = arr[i];
        }
    }

    return newArr;
}

如果可以打乱数组的顺序,某些情况下可以考虑将想删除的元素与数组最后一位元素交换,然后调用 pop 方法:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

contract Demo {
    uint[] public arr = [1, 2, 3, 4, 5];

    function removeAtIndex1(uint _index) public {
        for (uint i = _index; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
        }
        arr.pop();
    }

    function removeAtIndex2(uint _index) public {
        arr[_index] = arr[arr.length - 1];
        arr.pop();
    }
}



Mapping

contract Demo {
    // 定义一个 address => uint 的 mapping
    mapping(address => uint) public myBalance;

    // 获取指定值
    function getMyBalance() public view returns (uint) {
        return myBalance[msg.sender]; // 如果没有设置过该值, 则返回类型的默认值
    }

    // 添加/修改指定值
    function setMyBalance(uint _amount) public {
        myBalance[msg.sender] += _amount; // 如果没有设置过, 则基于类型的默认值进行更新
    }

    // 删除指定值
    function deleteMyBalance() public {
        delete myBalance[msg.sender]; // 重置为类型的默认值
    }
}

嵌套 mapping :

contract Demo {
    // 定义一个嵌套的 mapping
    mapping(address => mapping(address => uint)) public allowance;

    // 获取指定值
    function getAllowance(
        address _owner,
        address _spender
    ) public view returns (uint) {
        return allowance[_owner][_spender];
    }

    // 新增/修改指定值
    function setAllowance(address _spender, uint _amount) public {
        allowance[msg.sender][_spender] = _amount;
    }

    // 删除指定值
    function deleteAllowance(address _spender) public {
        delete allowance[msg.sender][_spender];
    }
}

demo - 简单的银行账户系统:

contract SimpleBank {
    mapping(address => uint) private balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }

    function checkBalance() public view returns (uint) {
        return balances[msg.sender];
    }
}

demo - 实现可迭代映射:

contract Demo {
    mapping(address => uint) public balance;
    mapping(address => bool) public isCustomer;
    address[] public customers;

    function deposit(address _customer, uint _amount) public {
        balance[_customer] += _amount;
        if (!isCustomer[_customer]) {
            customers.push(_customer);
            isCustomer[_customer] = true;
        }
    }

    function getCustomerBalance(address _customer) public view returns (uint) {
        require(isCustomer[_customer], "Customer does not exist");
        return balance[_customer];
    }

    function getCustomerBalanceByIndex(uint _index) public view returns (uint) {
        require(_index < customers.length && _index >= 0, "Index out of bounds");
        return balance[customers[_index]];
    }
}



Struct

创建 Struct 实例:

contract Demo {
    struct Student {
        uint id;
        string name;
    }
    Student[] public students;

    function addStudent1(string memory _name) public {
        // 按属性顺序创建 Struct 实例, 并添加到 students 数组
        students.push(Student(students.length, _name));
    }

    function addStudent2(string memory _name) public {
        // 按属性名创建 Struct 实例, 并添加到 students 数组
        students.push(Student({id: students.length, name: _name}));
    }

    function addStudent3(string memory _name) public {
        // 创建 Struct 实例, 但不指定属性值, 会使用默认值
        Student memory student;
        // 设置属性值
        student.id = students.length;
        student.name = _name;
        // 添加到 students 数组
        students.push(student);
    }
}

访问 Struct 实例属性:

    function getStudentInfoByIndex(
        uint _index
    ) public view returns (uint, string memory) {
        Student memory student = students[_index];
        return (student.id, student.name);
    }

修改 Struct 实例属性:

    function updateStudentNameByIndex(uint _index, string memory _name) public {
        Student storage student = students[_index];
        student.name = _name;
    }

删除 Struct 实例属性:

    function deleteStudentNameByIndex(uint _index) public {
        Student storage student = students[_index];
        delete student.name; // 将属性值重置为类型默认值
    }

删除 Struct 实例:

    function deleteStudentByIndex(uint _index) public {
        delete students[_index]; // 将该 Struct 实例的属性值都重置为对应类型默认值
    }



Enum

枚举值在内部表示为无符号整数,从 0 开始递增。枚举的默认值是其定义中的第一个值。

contract Demo {
    enum State {
        PENDING, // 0
        ACTIVE, // 1
        INACTIVE // 2
    }
    State public state; // 默认值为 PENDING, 即 0

    // 更新 state
    function updateState(State _state) public {
        state = _state;
    }

    // 重置 state
    function resetState() public {
        delete state; // 重置为默认值 PENDING, 即 0
    }

    // 获取 state
    function getState() public view returns (State) {
        return state;
    }
}

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Solidity是一种用于编写智能合约的高级编程语言,它被广泛应用于Ethereum区块链上的智能合约开发。比较复杂Solidity合约通常涉及多个函数、数据结构和逻辑,以下是一个简单示例: 合约名: ComplexContract 合约功能: ComplexContract合约实现一个简单的投票系统,可以添加候选人、对候选人进行投票以及获取候选人的得票数。 状态变量和数据结构: 1. uint public totalVotes; // 总票数 2. mapping(string => uint) public candidateVotes; // 候选人的得票数,以候选人姓名为键 3. struct Candidate { string name; // 候选人姓名 string party; // 候选人党派 } Candidate[] public candidates; // 候选人数组 函数: 1. function addCandidate(string memory _name, string memory _party) public { require(bytes(_name).length > 0 && bytes(_party).length > 0, "姓名和党派不能为空"); candidates.push(Candidate(_name, _party)); } // 添加候选人 2. function vote(string memory _candidateName) public { require(bytes(_candidateName).length > 0, "候选人姓名不能为空"); require(candidateVotes[_candidateName] == 0, "不能重复投票"); candidateVotes[_candidateName] += 1; totalVotes += 1; } // 对候选人进行投票 3. function getCandidateVotes(string memory _candidateName) public view returns (uint) { require(bytes(_candidateName).length > 0, "候选人姓名不能为空"); return candidateVotes[_candidateName]; } // 获取候选人的得票数 复杂Solidity合约通常还会包括更多功能,如删除候选人、修改投票结果等。以上是一个简单示例,但复杂Solidity合约的编写需要更加详细的设计和思考,以确保合约的正确性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值