Заработай свою долю из 1000 Sui
Зарабатывай очки репутации и получай награды за помощь в развитии сообщества Sui.
Explorer
Присоединяйтесь к сообществам и открывайте новые идеи.
Сообщества
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Лучшие публикацииТоп участников- 345
- 296
- 295
Move is an executable bytecode language used to implement custom transactions and smart contracts.
Лучшие публикацииТоп участников- 271
- 260
- 251
The InterPlanetary File System (IPFS) is a protocol, hypermedia and file sharing peer-to-peer network for storing and sharing data in a distributed file system.
Лучшие публикацииТоп участников- 25
- 20
- 20
Walrus is a decentralized storage and data availability protocol designed specifically for large binary files, or "blobs"
Лучшие публикацииТоп участников- 20
- 17
- 15
The Graph is a decentralized protocol for indexing and querying blockchain data. The Graph makes it possible to query data that is difficult to query directly.
Лучшие публикацииТоп участников- 2565
- 10
- 10
Aave is a decentralized non-custodial liquidity protocol where users can participate as depositors or borrowers.
Лучшие публикацииТоп участников- 148
- 138
- 74
Peera is a decentralized questions and answers protocol for Web3 where users can organize and store their interests and skills, creating a common community platform
Лучшие публикацииТоп участников- 328
- 286
- 225
Cyfrin Updraft is an education platform specializing on teaching the next generation of smart contract developers
Топ участников- 1780
- 75
- 60
Web3 (also known as Web 3.0) is an idea for a new iteration of the World Wide Web which incorporates concepts such as decentralization, blockchain technologies, and token-based economics.
Лучшие публикацииТоп участников- 397
- 193
- 141
Polygon is a decentralised Ethereum scaling platform that enables developers to build scalable user-friendly dApps with low transaction fees without ever sacrificing on security.
Лучшие публикацииAnkr makes accessing Web3 easy for those who want to build and earn on the future web. Ankr is the main infrastructure provider for Polygon, BNB Smart Chain, and Fantom.
Лучшие публикацииТоп участников- 89
- 43
- 34
Koii is a new way to design communications infrastructure that distributes computing authority across a wider group of personal devices.
Лучшие публикацииТоп участников- 402
- 188
- 80
Functionland is replacing Cloud Storage and Service Subscription economy by introducing a new category of products, called Blockchain-Attached Storage. It creates value by auto-minting crypto for the users and allocating a share to the developers.
Лучшие публикацииSolidity is an object-oriented, high-level language for implementing smart contracts. It is a curly-bracket language designed to target the Ethereum Virtual Machine (EVM).
Лучшие публикацииТоп участников- 76
- 50
- 46
Fractal Visions is a builder owned and operated creative web3 NFT project hub and a multifaceted & multidimensional experience. Bridging the gap between the physical and digital world.
Топ участников- 30
- 27
- 23
- Лучшие публикацииТоп участников
- 12
- 11
- 10
Vyper is a relatively new, pythonic programming language used to write smart contracts. Vyper targets Ethereum Virtual Machine making it virtually impossible for developers to code misleading programs.
Лучшие публикацииТоп участников- 40
- 22
- 20
Самые новые
- ДляSuiApr 24, 2025
Логика привязки к душе и шаблон возврата квитанции
#Логика привязки к душе и схема получения возврата Теперь перейдем к специальному шаблону проектирования, использующему механизм «родитель-потомок»:объекты, привязанные к душа. Объект, привязанный к душе, должен быть привязан к определенному владельцу и не подлежит постоянной передаче. Однако, возможно, вы захотите временно предоставить кому-либо доступ к нему в рамках одной транзакции (например, выполнить с ним какую-либо операцию), но при этом обязательно вернуть его вам к концу этой транзакции. Это достигается с помощью так называемого шаблонаReturnReceiption, представляющего собой разновидность паттерна «горячая картошка». ###Схема приготовления горячего картофеля по-суи Узор «горячая картошка» назван в честь детской игры: если вам вручат горячую картошку 🌡️🥔, вы не сможете ее удержать; вы должны быстро передать ее. С точки зрения Move, горячая картошка — это обычно предмет или ресурс, которые обязательно нужно съесть или передать в одну и ту же транзакцию, иначе транзакция завершится неудачей. Часто для этого нужно запретить удалять объект (чтобы его нельзя было просто проигнорировать или бросить) и разработать логику, согласно которой единственный способ избавиться от него — выполнить необходимое действие (например, вернуть кредит). Типичный вариант использования — «срочный» займ**: в ходе транзакции вы одалживаете несколько монет (получаете объект займа плюс «долговой» токен). Если вы не выплатите кредит до конца сделки, вы не сможете ее завершить, потому что у вас все еще есть долговой токен, на списание которого вы не имеете разрешения, что, по сути, вынуждает вас вернуть кредит или сделать аборт. ###Пример объекта, привязанного к душу Допустим, у нас есть объект SoulBound, и мы всегда хотим сохранить его первоначальный адрес владельца. Мы можем потребовать, чтобы, если кто-то «одолжил» объект (в качестве дочернего объекта, принадлежащего другому родителю), он должен вернуть его в той же транзакции. Как? Используя квитанцию о возврате товара. Ниже приведена упрощенная версия, вдохновленная документацией Sui: пример объектов, привязанных к душе module demo::soul_bound { use sui::transfer::{Self, Receiving}; use sui::object::UID; use sui::transfer; const EWrongObject: u64 = 0; /// A soul-bound object that cannot be permanently transferred. /// It has only key ability (no store), to tighten transfer/receive rules oai_citation_attribution:40‡docs.sui.io. public struct SoulBound has key { id: UID, data: u64 } /// A receipt that proves a SoulBound object must be returned. /// No abilities: cannot be copied, dropped, or stored (implicitly). public struct ReturnReceipt { /// The object ID of the soul-bound object that must be returned. object_id: UID, /// The address (or object ID) it must be returned to (the original owner). return_to: address } /// Allows the owner of parent to retrieve their SoulBound child. /// Returns the SoulBound object and a ReturnReceipt that compels return. public fun take_soul_bound(parent: &mut UID, sb_ticket: Receiving): (SoulBound, ReturnReceipt) { let sb = transfer::receive(parent, sb_ticket); // receive SoulBound (only this module can do it, since SoulBound has no store) oai_citation_attribution:41‡docs.sui.io let receipt = ReturnReceipt { object_id: sb.id, return_to: parent.to_address() }; (sb, receipt) } /// Return a SoulBound object using the ReturnReceipt. /// This must be called in the same transaction after take_soul_bound. public fun return_soul_bound(sb: SoulBound, receipt: ReturnReceipt) { // Verify the receipt matches this SoulBound object assert!(sb.id == receipt.object_id, EWrongObject); // Send the SoulBound object back to the original owner address transfer::transfer(sb, receipt.return_to); // (ReturnReceipt is consumed/destroyed here as function param) } } В этом дизайне: SoulBound — это объект, предназначенный только для ключа. Отказав ему в хранении, мы запрещаем использовать на нем команды public_transfer или public_receive, то есть передавать или получать его можно только с помощью функций определяющего модуля (при условии использования нашей собственной логики). take_soul_bound (аналогично «get_object» в документации) — это функция, которую владелец вызывал бы, чтобы забрать свой объект, привязанный к душе, у какого-либо родителя. Она вызывает transfer: :receive для получения объекта SoulBound. Поскольку у SoulBound нет хранилища, этот вызов разрешен только здесь, в модуле (и это нормально). Затем создается структура ReturnReceipt, содержащая идентификатор объекта, привязанного к душе, и адрес, к которому нужно вернуться (адрес родителя). Мы возвращаемобообъект и чек. ReturnReceipt не может копировать, сохранять или копировать (мы ничего не декларировали, поэтому к нему относятся как к ресурсу, который нельзя удалить или дублировать). Это означает, что транзакциядолжнас ней что-то сделать**; в противном случае это останется неиспользованным ресурсом и виртуальная машина не допустит успешного завершения транзакции. По сути, ReturnReceipt — это наш популярный токен 🔥🥔. Единственное, что можно сделать с ReturnReceipt, — это вызвать return_soul_bound (или аналогичную назначенную функцию) в той же транзакции. В return_soul_bound мы проверяем, совпадает ли идентификатор объекта SoulBound с записью чека (чтобы никто не попытался вернуть другой объект с неправильным чеком). Затем мы вызываем команду transfer: :transfer (sb, receipt.return_to) и отправляем объект SoulBound обратно по адресу, указанному в чеке (первоначальному владельцу). Это эффективно восстанавливает объект, привязанный к душе, на его законное место. ReturnReceipt используется в качестве аргумента (таким образом, уничтожается). Если пользователь попытается завершить транзакцию без вызова return_soul_bound, он все равно будет держать в руках ReturnReceipt (из выходных данных take_soul_bound). Поскольку ReturnReceipt не теряется, виртуальная машина Move откажется завершить транзакцию (в Move вы не можете просто сбросить ресурс; его нужно использовать или где-то хранить). Транзакция будет прервана или признана недействительной, то есть вся операция будет отменена.Результат: вы не можете просто сбежать с объектом, привязанным к душе; если вы его не вернете, запрос не будет выполнен и он останется у родителя. С момента вызова take_soul_bound до вызова return_soul_bound в транзакции у вас есть доступное значение объекта SoulBound. Предположительно, для выполнения с ним некоторых разрешенных операций (например, для чтения или использования по мере необходимости). Но выобязанывернуть его до завершения транзакции, поскольку чек был подтвержден в силе. Этот паттерн часто называют «привязанным к душе = не могу расстаться с владельцем», но точнее сказать, что он может остаться в течение одной транзакции в качестве дочернего объекта с гарантией возврата. Это все равно, что взять книгу в библиотеку: ее нужно вернуть до закрытия библиотеки на целый день 😅. Почему бы просто не передавать её вообще? Есть сценарии, в которых полезно временно перенести объект в другой объект (или контекст). Одним из примеров является контекстобщего объекта: возможно, объект SoulBound во время некоторой операции хранится в общем объекте и должен быть удален первоначальным владельцем. Другой вариант — разрешить контролируемую композицию — возможно, вы захотите разрешить какому-то модулю работать с вашим объектом, передав его объекту этого модуля, а затем вернуть обратно. Сделав использование только ключа SoulBound, мы позаботились о том, чтобы ни один внешний пользователь public_receive не смог получить его без участия нашего модуля. Используя чек, мы обязуемся соблюдать правила возврата товара. В комментарии, приведенном в примере кода Суи, даже отмечается, что ReturnReceipt не позволяет обменивать их местами: если за одну транзакцию было изъято два предмета, переплетенных с душой, каждому чеку присваивается определенный идентификатор объекта, поэтому вы не сможете перепутать их и вернуть не тот предмет, чтобы обмануть его. Обобщая идею: Шаблон ReturnReceipt можно использовать всякий раз, когда вы хотите принудительно вернуть объект. Флэш-кредиты используют аналогичную концепцию (кредитный токен и долговой токен, который необходимо погасить). Каждый раз, когда у вас есть инвариант «объект X должен быть возвращен по адресу Y к концу tx», вы можете создать ресурс чеков, подтверждающий его. ###Краткое описание: Объекты, привязанные к душа**: только ключи, извлекаемые только по логике модуля. ReturnReceipt**: фиктивный ресурс, возвращаемый вместе с объектом для обеспечения его возврата. Он не удаляется, поэтому пользователь должен вызвать функцию return в противном случае. Горячая картошка**: если вы держите в руках квитанцию о возврате товара, лучше обработать ее (вернуть объект) до того, как «музыка остановится» (транзакция завершится). Если объект не будет возвращен, транзакция не будет успешно выполнена — внесенные изменения будут отменены, что позволит эффективно соблюдать правило, связанное с душой. На этом мы рассмотрели основные концепции отношений между родителями и детьми в Sui Move! ##5. Структура проекта и стратегия тестирования (готовы к использованию GitHub) Чтобы закрепить эти концепции, вы можете создать проект Sui Move и поэкспериментировать с примерами. Вот предлагаемый макет проекта, включающий модули для приведенных выше примеров. Можно компилировать и запускать модульные тесты или использовать интерфейс командной строки Sui для взаимодействия с ними. parent_child_demo/ ├── Move.toml ├── sources/ │ ├── toy_box.move (Parent & child in same module example) │ ├── parcel.move (Child module for Parcel) │ ├── warehouse.move (Parent module for Warehouse, uses public_receive) │ └── soul_bound.move (SoulBound and ReturnReceipt module) └── tests/ └── parent_child_test.move (Integration tests for the modules) Move.toml: Обязательно укажите фреймворк Sui и любые адреса вашего пакета. Например: [package] name = "parent_child_demo" version = "0.0.1" dependencies = [ { name = "Sui", git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework", rev = "devnet" } ] [addresses] demo = "0x0" (Используйте правильный адрес вместо 0x0, если того требует Sui, или именованный адрес, который вы укажете при публикации. ) * В каталоге исходников: toy_box.move**может содержать пример модуля: :toy_box из части 2 с определениями игрушек и коробок и функцией take_toy. parcel.moveиwarehouse.move**будут содержать модули из части 3. soul_bound.move**будет содержать модуль из части 4. Каждый модуль должен использовать sui::... по мере необходимости для передачи, объекта, tx_context и т. д., как показано в примерах. Затем tests/parent_child_test.move может импортировать эти модули и моделировать сценарии: module demo::parent_child_test { use 0xYourAddr::toy_box; use 0xYourAddr::warehouse; use 0xYourAddr::parcel; use 0xYourAddr::soul_bound; use sui::tx_context::TxContext; #[test] fun test_toy_withdraw() { let ctx = TxContext::new(); // pseudo, context is usually provided let my_box = toy_box::Box { id: object::new(&mut ctx) }; let my_toy = toy_box::Toy { id: object::new(&mut ctx), name: b"Ball".to_vec() }; // Transfer toy into the box transfer::transfer(my_toy, my_box.id); // Now simulate receiving it back let ticket = transfer::Receiving{ /.../ }; // In real test, use transfer::make_receiver or a transaction call let returned_toy = toy_box::take_toy(&mut my_box, ticket); assert!(returned_toy.name == b"Ball".to_vec()); } // Additional tests for warehouse/parcel and soul_bound can be written similarly. } Вышесказанное является концептуальной иллюстрацией. На практике тестовый контекст Sui может отличаться — возможно, вам придется использовать transfer: :public_transfer в тестах при переносе в объект (если это не входит в модуль) и использовать функцию Получение из контекста транзакции. В Sui предусмотрена функция transfer: :make_receiver (функция, предназначенная только для тестирования), которая позволяет создать файл Receiving с указанием идентификатора и версии, что полезно в модульных тестах для моделирования ввода дочернего объекта. Выполнение тестов: Вы можете запустить тест sui move, который выполнит функции # [test]. Или разверните пакет в локальной сети Sui и вызовите функции ввода через интерфейс командной строки или SDK, чтобы наблюдать за поведением: Создайте посылку, создайте склад, вызовите transfer: :public_transfer через интерфейс командной строки, чтобы поместить посылку на склад, а затем вызовите withdraw_parcel. Создайте объект SoulBound (например, сделав запись забавной), передайте ее какому-нибудь родительскому объекту (или общему объекту), затем вызовите take_soul_bound за одну транзакцию и пропустите return_soul_bound, чтобы увидеть, что транзакция завершилась неудачно (ожидается), вместо того чтобы включить обратный вызов, чтобы убедиться в успехе. Каждая часть этого проекта посвящена одной из тем: toy_box.move: базовый родитель-ребенок и получение. parcel.move и warehouse.move: межмодульные дочерние элементы и public_receive. soul_bound.move: в переплете с чеком возврата товара. Поэкспериментировав с ними, вы углубите свое понимание объектной модели Суи. Код разработан таким образом, чтобы он был образовательным, и его не следует использовать в рабочей среде без проверок безопасности, но он служит хорошей отправной точкой. Вывод: Функциональность родительско-дочерних объектов Sui Move очень мощна. Она позволяет создавать сложные структуры данных в блокчейне (например, запасы, кошельки, коллекции) с детальным контролем доступа. Сочетание transfer: :receive/public_receive и системы типов Move позволяет извлекать дочерние объекты только авторизованным кодом, а такие шаблоны, как ReturnReceipt, позволяют применять правила временного владения (привязка к персональным данным, мгновенные займы и т. д.). Мы привели несколько забавных аналогий и смайликов, но, в конце концов, это надежные инструменты для разработчиков. А теперь иди и создай магию из вложенных объектов! 🚀🔥 Когда объект передается другому объекту вместо адреса учетной записи, они образуют отношениеродитель-дочерь. Вы можете представить себе это следующим образом: Родитель**= объект-контейнер Ребенок**= вещь, помещенная внутрь Move не имеет значения, переходите ли вы на аккаунт или на идентификатор объекта. Он просто перемещается. public struct Parent has key { id: UID, name: String, } public struct Child has key { id: UID, description: String, } ##Создание родительских и дочерних объектов Родитель должен быть изменчивым и существовать. Нельзя складывать вещи в неизменную коробку!
1 - ДляSuiApr 24, 2025
Межмодульное управление детьми с помощью public_receive
Это третья часть серии «Объекты для родителей и детей в режиме Sui Move». Иногда ваши родительские и дочерние типы определяются в разных модулях или даже в разных пакетах. Например, у вас может быть обычный объект Warehouse, в котором можно хранить любые объекты Parcel. Модуль Warehouse хочет удалить дочерний объект Parcel, но тип участка определен в другом месте. В таких случаях мы используем transfer: :public_receive, который является межмодульным двоюродным братом receive. ###получать и public_receive Как мы уже видели, transfer: :receive можно вызвать только в модуле, который определяет T (или имя друга), поскольку для этого не требуется T: store. Верификатор байт-кода Move фактически гарантирует, что в любом получаемом вызове используется тип T из текущего модуля. Это ограничение безопасности для объектов, содержащих только ключи. transfer: :public_receive — это вариант, который требует хранилища T: key +, но позволяет получать данные за пределами модуля T. Другими словами, если тип объекта можно хранить (то есть ему разрешено свободно существовать в глобальном хранилище), то любой модуль (с идентификатором родительского объекта &mut) может получить его с помощью public_receive. Это идеально подходит для случаев, когда родительский модуль отличается от дочернего модуля. Зачем нужен магазин? Потому что хранилище отмечает, что объект можно безопасно сохранить и передать за пределы определяющего модуля. Объекты, содержащие только ключи, могут иметь собственные инварианты, которые исходный модуль хочет использовать при передаче и получении. Исключая объекты из public_receive, Sui заставляет разработчиков обрабатывать их в модуле (как мы увидим в случае с объектами, привязанными к душе). Если у объекта есть хранилище, оно более разрешительно, а Sui позволяет управлять им извне с помощью общей логики передачи/получения. ###Пример: отдельные родительские и дочерние модули Давайте проиллюстрируем простой сценарий: склад, в котором хранятся объекты Parcel. Тип участка определяется в отдельном модуле, а склад — в другом. Мы покажем, как Хранилище может получить дочернюю посылку с помощью public_receive. module demo::parcel { // Child module use sui::object::{Self, UID}; use sui::tx_context::{Self, TxContext}; /// A parcel object that can be stored in a Warehouse. /// It has both key and store, so it can be transferred across modules. struct Parcel has key, store { id: UID, contents: vector } public entry fun create_parcel(contents: vector, ctx: &mut TxContext): Parcel { Parcel { id: object::new(ctx), contents } } } module demo::warehouse { // Parent module use sui::transfer::{Self, Receiving, public_receive}; use demo::parcel::{Self, Parcel}; use sui::object::{UID}; use sui::tx_context::{Self, TxContext}; struct Warehouse has key { id: UID, location: address } public entry fun create_warehouse(location: address, ctx: &mut TxContext): Warehouse { Warehouse { id: object::new(ctx), location } } /// Receive a Parcel that was sent to this Warehouse. /// Returns the Parcel to the caller (transferred to caller's address). public entry fun withdraw_parcel( warehouse: &mut Warehouse, parcel_ticket: Receiving, ctx: &mut TxContext ): Parcel { // Using public_receive because Parcel is defined in another module and has store let parcel = public_receive(&mut warehouse.id, parcel_ticket) oai_citation_attribution:27‡docs.sui.io oai_citation_attribution:28‡github.com; // Transfer the parcel to the transaction sender (so the caller gets ownership) transfer::transfer(parcel, tx_context::sender(ctx)); // We return nothing because we've transferred the Parcel out to the caller. } } Давайте разберемся, что происходит в withdraw_parcel: Мы называем public_receive (&mut warehouse.id, parcel_ticket). Поскольку в Parcel есть возможность хранения посылок, этот звонок разрешен, даже если нас нет в модуле посылок. На капоте производится та же процедура проверки и извлечения информации, что и при получении, но в разных модулях эта процедура разрешена, так как система хранения показывает, что делать это безопасно. https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/sui-framework/sources/transfer.move#:~:text=public%20fun%20public_receive,T%3E%29%3A%20T Затем мы немедленно передаем полученную посылку на адрес звонящего (tx_context: :sender (ctx)). Этот шаг гарантирует, что посылка покинет склад и отправится пользователю, инициировавшему вывод средств. Кроме того, мы могли бы просто вернуть посылку из этой функции, и Суй воспримет ее как выходные данные, принадлежащие адресу вызывающего абонента (поскольку это выходные данные функции ввода). Выполнение явной передачи более подробное задание, но оно позволяет понять, что происходит (и позволяет нам выполнить любые проверки перед выпуском объекта). Зачем включать магазин в посылку? Если в Parcel отсутствовала возможность хранения (то есть у нее был только ключ), вызов public_receive в demo: :warehouse не скомпилировался — Sui заставляет T оставить в памяти public_receive. В этом случае нам придется забрать посылку с помощью команды receive в самом модуле обработки посылок (или использовать дружеские отношения), что усложнит межмодульное проектирование. Добавляя хранилище в Parcel, мы фактически говорим, что «этот объект можно свободно перемещать и принимать внешними модулями». Именно это и нужно для стандартного шаблона контейнера. Шаблон вызова функций: Чтобы использовать их в транзакции, необходимо выполнить следующую последовательность действий: 1.Депозит (перевод на объект) :Позвоните в transfer: :public_transfer (parcel_obj, @warehouse_id), чтобы отправить посылку на склад. При этом владелец посылки считается складом. (Здесь мы используем public_transfer, потому что оно находится за пределами модуля Parcel и в Parcel есть магазин. В модуле посылки также подойдет простой перевод.) Выведите деньги (получите обратно) :Позже вызовите команду withdraw_parcel (warehouse_obj, «Получение» (parcel_id,...)). Справку о получении можно получить с помощью SDK, указав идентификатор посылки и ее последнюю версию. Функция вызовет public_receive, а затем передаст вам посылку. После вызова withdraw_parcel владелец посылки возвращается на адрес (ваш), так что это снова обычный объект, принадлежащий адресу. Склад больше не владеет им. Межмодульные аспекты: Обратите внимание, что модулю Warehouse необходимо знать тип посылки (мы используем demo: :parcel: :Parcel). Это связано с тем, что мы явно указываем «Получение» как «Получение». Если вам нужен действительно универсальный контейнер, в который можно было бы поместить объекты любого типа, вам придется использовать дженерики или другой подход (возможно, динамические поля со стиранием типов). Но в большинстве случаев вы знаете, каких типов детей вы ожидаете. Почему public_receive вместо простого вызова receive? Если мы попробуем transfer: :receive (&mut warehouse.id, parcel_ticket) в модуле склада, верификатор Move отклонит запрос, так как в demo: :warehouse не определена посылка. Sui предоставляет public_receive в качестве удачного способа сделать это, добавив дополнительную проверку способностей (требующую сохранения). Аналогичным образом, Sui использует transfer против public_transfer, freeze_object против public_freeze_object и т. д., следуя той же схеме: версии public_ предназначены для использования вне определяющего модуля и требуют хранения. Не забудьте разрешение родителя: Даже если вы используете public_receive, вам все равно нужен этот &mut warehouse.id. Мы его получили, потому что withdraw_parcel находится в модуле Warehouse и принимает &mut Warehouse. Таким образом, забрать посылку может только тот, кто так позвонит (владелец склада). Если складской модуль не предоставлял такую функцию публично, никто также не мог бы вызвать public_receive извне для своих дочерних элементов. Таким образом, кросс-модуль не обходит родительский контроль; он просто позволяет родительскому коду работать с дочерними типами типов, которые он не определил. Примечание о возможности хранения: Предоставление хранилища объектов делает его более гибким, но немного менее ограниченным — любой модуль, имеющий ссылку на родительский объект, может удалить его с помощью public_receive. Если вы хотитеограничитьспособ извлечения объекта (например, ввести собственную логику или запретить простое извлечение), вы можете намеренно сделать его доступным только по ключу. Пример этого мы рассмотрим на примере объектов, привязанных к душе. В таких случаях вы можете реализовать собственную функцию получения, а не полагаться на public_receive. Подводя итог этому, можно сказать, что public_receive — ваш друг в управлении дочерними объектами, определенными в других модулях, при условии, что эти объекты можно хранить. Он позволяет создавать кроссмодульные системы (например, наш склад/посылок), сохраняя при этом право собственности и контроль доступа. Просто не забудьте включить хранилище дочерних типов и использовать public_transfer при отправке их родителю из-за пределов модуля.
2
Без ответа
- ДляFunctionlandApr 14, 2025
Настройка NAS или BAS
Пытаясь использовать свою башню в качестве NAS, я последовал инструкциям, но вот результат: PS C:\WINDOWS\system32 > ssh pi @fulatower ssh: не удалось разрешить fulatower имени хоста: хост неизвестен. PS C:\WINDOWS\system32 > ssh pi @192 .168.1.150 ssh: подключение к хосту 192.168.1.150, порт 22: время ожидания соединения истекло
00 Что произойдет, если я не получу ETH через мост Sui?
Я использовал мост Sui для перевода некоторого количества ETH, но пока не воспользовался им, так как комиссии довольно высоки. Что произойдет, если я оставлю деньги невостребованными?
00
В тренде
- Foksa225ДляPeera MetaJul 25, 2022
How to create an account
To create an account on the Peeranha website you need to log in first. Peeranha supports four wallets you can log in with: Torus, MetaMask, WalletConnect, and Coinbase. Note: If you are new to Web3 we recommend you to use Torus. Log in with Torus Click Log in. Select the checkbox I agree to the Terms and Conditions and Privacy Policy. Choose Torus in the pop-up window. Select any of the suggested ways you want to sign in or enter your email address. You are now logged in and have an account. In your profile section, you can add more detailed information about yourself and track your progress and achievements. To edit your profile, click Profile and select Edit. Enter all the information that you want to be visible in your profile.
5 - loth.broke110ДляPolygonMar 31, 2025
Используете heimdallcli в докеризованной локальной сети?
heimdallcliЯ пытаюсь использовать его matic-cliв своей локальной докеризованной сети, которую я использовал. heimdallcli tx gov submit-proposal param-change {pathToProposalJSONFile} --validator-id {validatorID} --chain-id {chainID}Моя главная цель — отправить предложение с помощью этой команды:. Однако я столкнулся с ошибкой: «Конфигурационный файл «heimdall-config» не найден в «/var/lib/heimdall/config"'. Похоже, что директория конфигурации не существует в среде Docker, хотя я вижу журналы, указывающие на то, что Heimdall работает. heimdallcliКак решить эту проблему и заставить команду работать?
54