Ethereum 我的艺术实验spacecans.com以太坊气体优化

Ethereum 我的艺术实验spacecans.com以太坊气体优化,ethereum,solidity,web3,Ethereum,Solidity,Web3,所以我在给一些研究化学进行/r/微量给药,我突然想到我需要做一些artsy区块链的东西。这是两个漂浮在太空中的锡罐,你可以在上面宣传你所谓的垃圾桶或其他东西。它目前正在Rinkeby测试网上运行。你可以用乙醚购买这些锡罐的部分标签,在上面贴上自定义图像,并将其链接到网站 然而,我的智能合约在天然气和安全方面仍然需要一些优化。目前,一笔交易中可以购买的最大面积是32x32个零件中的8x8个零件,因为buyTabs功能显然消耗了太多的汽油。(这是因为块大小限制吗?) 关于天然气优化,有什么建议给坚实

所以我在给一些研究化学进行/r/微量给药,我突然想到我需要做一些artsy区块链的东西。这是两个漂浮在太空中的锡罐,你可以在上面宣传你所谓的垃圾桶或其他东西。它目前正在Rinkeby测试网上运行。你可以用乙醚购买这些锡罐的部分标签,在上面贴上自定义图像,并将其链接到网站

然而,我的智能合约在天然气和安全方面仍然需要一些优化。目前,一笔交易中可以购买的最大面积是32x32个零件中的8x8个零件,因为buyTabs功能显然消耗了太多的汽油。(这是因为块大小限制吗?)

关于天然气优化,有什么建议给坚实的新手吗?谢谢

这是我的智能合约:

以下是网站:

pragma solidity>=0.4.22应付地址)参考链接; 结构选项卡{ 应付业主地址; uint256价格;///下次购买的价格 字节32[2]链接URL; bytes32[3]imageUrl; ///用于跨越多个尺寸为X、Y的选项卡的图像 uint8 x;///x索引[0,x-1] uint8x; uint8 y;///y索引[0,y-1] uint8y; } 结构托佩{ 应付业主地址; uint256金额; } 构造函数()公共{ 主席=msg.sender; } 函数uint2str(uint i)内部纯返回(字符串内存){ 如果(i==0)返回“0”; uint j=i; 单位长度; 而(j!=0){ 长度++; j/=10; } 字节内存bstr=新字节(长度); uint k=长度-1; 而(i!=0){ bstr[k--]=字节(uint8(48+i%10)); i/=10; } 返回字符串(bstr); } 函数bytes32ToString(bytes32x)内部纯返回(字符串内存){ 字节内存字节串=新字节(32); uint charCount=0; 对于(uint j=0;j<32;j++){ 字节字符=字节(字节32(uint(x)*2**(8*j)); 如果(字符!=0){ ByteString[charCount]=字符; charCount++; } } bytes memory bytesStringTrimmed=新字节(charCount); 对于(uint j=0;j对于(uint8 yt=y1;yt您的问题更适合于性能改进3个建议。1.使用
uint256
而不是
uint8
。2.使用
映射
而不是
数组
。3.避免
用于
循环。1.uint8在我的选项卡结构中不需要更少的气体,因为它使用更少的存储空间吗?2.我只使用数组,beca使用我迭代它们。3.我设法摆脱了Buytab中的第一个for循环,谢谢!1.请阅读:.2.如果可能,请使用映射。如果必须使用for循环,并且它不支持气体限制,则必须更改算法。
address payable chairperson;
uint8 public constant N = 32;
uint8 public constant M = 32;
uint256 public constant initialTabPrice = 1 finney;
uint256 public constant feePercent = 15;
uint256 public constant referralPercent = 30;
uint256 public constant appreciationPercent = 200;
Tab[N][M] public tabs;
mapping (bytes32 => address payable) referralLinks;

struct Tab {
    address payable owner;
    uint256 price; /// Price for next purchase
    bytes32[2] linkUrl;
    bytes32[3] imageUrl;

    /// Used for images spanning over multiple tabs with dimensions X,Y
    uint8 x; /// x index [0, X-1]
    uint8 X; 
    uint8 y; /// y index [0, Y-1]
    uint8 Y;
}

struct ToPay {
    address payable owner;
    uint256 amount;
}

constructor() public {
    chairperson = msg.sender;
}

function uint2str(uint i) internal pure returns (string memory){
    if (i == 0) return "0";
    uint j = i;
    uint length;
    while (j != 0){
        length++;
        j /= 10;
    }
    bytes memory bstr = new bytes(length);
    uint k = length - 1;
    while (i != 0){
        bstr[k--] = byte(uint8(48 + i % 10));
        i /= 10;
    }
    return string(bstr);
}

function bytes32ToString(bytes32 x) internal pure returns (string memory) {
    bytes memory bytesString = new bytes(32);
    uint charCount = 0;
    for (uint j = 0; j < 32; j++) {
        byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
        if (char != 0) {
            bytesString[charCount] = char;
            charCount++;
        }
    }
    bytes memory bytesStringTrimmed = new bytes(charCount);
    for (uint j = 0; j < charCount; j++) {
        bytesStringTrimmed[j] = bytesString[j];
    }
    return string(bytesStringTrimmed);
}

function getTabs(uint8 x1, uint8 y1, uint8 x2, uint8 y2) external view returns(string memory) {
    string memory res = "";
    for (uint8 yt = y1; yt <= y2; yt++) {
        for (uint8 xt = x1; xt <= x2; xt++) {
             res = string(abi.encodePacked(res, ",", uint2str(getTabPrice(xt,yt)),  ",", bytes32ToString(tabs[xt][yt].linkUrl[0]), bytes32ToString(tabs[xt][yt].linkUrl[1]), ",", bytes32ToString(tabs[xt][yt].imageUrl[0]), bytes32ToString(tabs[xt][yt].imageUrl[1]), bytes32ToString(tabs[xt][yt].imageUrl[2]), "#", uint2str(tabs[xt][yt].x), ".", uint2str(tabs[xt][yt].X), ".", uint2str(tabs[xt][yt].y), ".", uint2str(tabs[xt][yt].Y)));
        }
    }  
    return res;
}

function getTabPrice(uint8 x, uint8 y) internal view returns(uint256) {
    if (tabs[x][y].price == 0) {
        return initialTabPrice;
    }
    return tabs[x][y].price;
}

function getTabOwner(uint8 x, uint8 y) internal view returns(address payable) {
    if (tabs[x][y].price == 0) {
        return chairperson;
    }
    return tabs[x][y].owner;
}
// string calldata linkUrl, string calldata imageUrl, string calldata referral

function buyTabs(uint8[4] calldata z, bytes32[6] calldata s) external payable {
    /// z: x1, y1, x2, y2
    /// Calculate combined price for asked tabs
    uint8 xt;
    uint8 yt;
    uint256 price = 0;
    uint256 tabPrice;
    address payable tabOwner;

    for (xt = z[0]; xt <= z[2]; xt++) {
        for (yt = z[1]; yt <= z[3]; yt++) {
            price += getTabPrice(xt,yt);
        }
    }

    /// Check if payment is sufficient
    assert(msg.value >= price);

    ToPay[1024] memory toPay;

    /// Pay previous owner and assign new owner and new price
    for (xt = z[0]; xt <= z[2]; xt++) {
        for (yt = z[1]; yt <= z[3]; yt++) {
            tabPrice = getTabPrice(xt,yt);
            tabOwner = getTabOwner(xt,yt);

            //tabOwner.transfer((tabPrice * (100-feePercent)) / 100);
            for(uint i=0; i<=toPay.length;i++) {
                if (toPay[i].amount == 0) {
                    //toPay[i] = ToPay(tabOwner, (tabPrice * (100-feePercent)) / 100);
                    toPay[i].owner = tabOwner;
                    toPay[i].amount = (tabPrice * (100-feePercent)) / 100;
                    break;
                }

                if (toPay[i].owner == tabOwner) {
                    toPay[i].amount += (tabPrice * (100-feePercent)) / 100;
                    break;
                }
            }

            tabs[xt][yt] = Tab(msg.sender, tabPrice * appreciationPercent / 100, [s[0], s[1]] , [s[2], s[3], s[4]], xt-z[0], z[2]-z[0]+1, yt-z[1], z[3]-z[1]+1);
        }
    }

    for(uint i=0; i<=toPay.length;i++) {
        if (toPay[i].amount == 0) {
            break;
        }
        toPay[i].owner.transfer(toPay[i].amount);
    }

    if (s[5][0] != 0) {
        referralLinks[s[5]].transfer(address(this).balance * referralPercent / 100);
    }

    /// Remaining funds are fees
    chairperson.transfer(address(this).balance);
}

function setReferralLink(bytes32 linkName) external {
    referralLinks[linkName] = msg.sender;
}

function retrieveLostEther() public {
    assert(msg.sender == chairperson);
    msg.sender.transfer(address(this).balance);
}