"Hello World" смарт-контракт для TON за 15 минут
Project ManagerThis tutorial is available in English
Цель гайда: понять как быстро разворачивать смарт-контракты в сети TON для самых-самых новичков.
Что сделаем: подготовим необходимые компоненты, развернём смарт-контракт в котором будет функция hello_world. Обратимся к этой функции из вне, и получим в ответ 1234567890
Гайд предназначен для ОС Ubuntu 18.04/20.04 (Server и Desktop), для других ОС этот гайд может не подойти.
upd: Если гайд выглядит страшным - можно развернуть смарт-контракт за 2 минуты через https://deployer.tonsc.org , но гайд лучше прочесть чтоб понять суть.
Смарт-контракт будем разворачивать в testnet
Для развёртки в mainnet: в п.19 testnet.ton.sh заменить на ton.sh, п.20 можно пропустить, а в п.21 и п.22 заменить testnet-global.config.json на global.config.json
Поехали:
1. Подключаемся к серверу по SSH или открываем Терминал, затем:
sudo -i {если система запросила пароль - вводим, затем enter}
2. Если Вы ещё не устанавливали mytonctrl - устанавливаем (если ПК/сервер не мощный, то может занять ~15 мин, так что смело идём за чаем/кофе после запуска установки):
wget https://raw.githubusercontent.com/igroman787/mytonctrl/master/scripts/install.sh sudo bash install.sh -m lite
3. Компилируем исполняемый файл func:
cd /usr/bin/ton/ && make func
4. Создаём необходимую переменную среды:
export FIFTPATH=/usr/src/ton/crypto/fift/lib:/usr/src/ton/crypto/smartcont
5. Загружаем глобальный конфиг для mainnet и testnet:
wget https://newton-blockchain.github.io/global.config.json wget https://newton-blockchain.github.io/testnet-global.config.json
6. Создаём generate.fif файл, на который будет ссылаться наш .sh файл из п.9
cd /usr/src/ton/crypto/smartcont && nano generate.fif
7. Вставляем код:
#!/usr/bin/fift -s "TonUtil.fif" include "Asm.fif" include 5 :$1..n $1 parse-workchain-id =: wc // set workchain id from command line argument $2 parse-int =: subwallet-id $3 "/root/sc" replace-if-null =: file-base $4 "/root/sc.fif" replace-if-null =: fif-code fif-code include <b 0 32 u, subwallet-id 32 u, file-base +".pk" load-generate-keypair constant wallet_pk B, b> null <b b{0011} s, 3 roll ref, rot ref, swap dict, b> dup ."StateInit: " <s csr. cr dup hashu wc swap 2dup 2constant wallet_addr ."new wallet address = " 2dup .addr cr 2dup file-base +".addr" save-address-verbose ."Non-bounceable address (for init): " 2dup 7 .Addr cr ."Bounceable address (for later access): " 6 .Addr cr <b subwallet-id 32 u, -1 32 i, 0 32 u, b> dup ."signing message: " <s csr. cr dup hashu wallet_pk ed25519_sign_uint rot <b b{1000100} s, wallet_addr addr, b{000010} s, swap <s s, b{0} s, swap B, swap <s s, b> dup ."External message for initialization is " <s csr. cr 2 boc+>B dup Bx. cr file-base +".boc" tuck B>file ."(Saved wallet creating query to file " type .")" cr
8. Выходим с сохранением:
{ctrl+x -> y -> enter}
upd: Более подробный разбор кода из п.7
9. Создаём .sh файл, который позволит скомпилировать файл нашего будущего смарт-контракта (.fc) в .fif файл, а на основе .fif сгенерировать .addr, .pk, .boc файлы, и получить адрес смарт-контракта:
cd /usr/bin/ton/ && nano compile.sh
10. Вставляем код:
#!/bin/bash fcDir=$1 workchainId=$2 subwalletId=$3 if [ -z "${workchainId}" ] then workchainId=0 fi if [ -z "${subwalletId}" ] then subwalletId=0 fi funcPath="/usr/bin/ton/crypto/func" fiftPath="/usr/bin/ton/crypto/fift" fiftLibPath="/usr/src/ton/crypto/fift/lib" smartcontPath="/usr/src/ton/crypto/smartcont" stdlibPath="${smartcontPath}/stdlib.fc" fcNames=$(ls ${fcDir}/*.fc) fcPath=${fcNames[0]} fcFullName=$(basename $fcPath) fcShortName=${fcFullName:0:-3} fifPath="${fcDir}/${fcShortName}.fif" toFifCmd="${funcPath} -SPA ${stdlibPath} ${fcPath} -o ${fifPath}" ${toFifCmd} toGenerateCmd="${fiftPath} -I ${fiftLibPath}:${smartcontPath} -s generate.fif ${workchainId} ${subwalletId} ${fcDir}/${fcShortName} ${fifPath}" generateResult=$(${toGenerateCmd}) rawAddr=${generateResult#*new wallet address = } rawAddr=${rawAddr%(Saving address to file*} nonBounceableAddr=${generateResult#*Non-bounceable address (for init): } nonBounceableAddr=${nonBounceableAddr%Bounceable*} bounceableAddr=${generateResult#*Bounceable address (for later access): } bounceableAddr=${bounceableAddr%signing message:*} echo -e "\nRaw address: ${rawAddr}\nNon-bounceable address: ${nonBounceableAddr}\nBounceable address: ${bounceableAddr}"
11. Выходим с сохранением:
{ctrl+x -> y -> enter}
12. Разрешаем исполнять файл compile.sh:
chmod +x compile.sh
13. Создаём директорию с нашим проектом и переходим в неё:
mkdir /srv/HelloWorldSC && cd /srv/HelloWorldSC
14. Берём за основу код смарт-контракта кошелька wallet3-code.fc
Копируем его в текущую директорию как sc.fc (sc - smart-contract):
cp /usr/src/ton/crypto/smartcont/wallet3-code.fc ./sc.fc
15. Открываем sc.fc редактором:
nano sc.fc
16. Добавляем самый в конец файла нашу функцию hello_world:
int hello_world() method_id { return 1234567890; }
17. Выходим с сохранением:
{ctrl+x -> y -> enter}
18. Запускаем compile.sh, в аргументах передаём директорию с проектом где лежит .fc файл, и указываем workchain_id 0 (если в будущих смарт-контрактах собираетесь взаимодействовать со смарт-контрактом электора, то указывайте workchain_id -1):
/usr/bin/ton/compile.sh /srv/HelloWorldSC 0
19. Копируем адрес смарт-контракта (он отобразится в консоли как Bounceable address) и переводим на него 1 TON
Проверяем поступление монет по ссылке (заменить "АДРЕС_СМАРТКОНТРАКТА"):
https://testnet.ton.sh/address/АДРЕС_СМАРТКОНТРАКТА
20. Самый простой вариант зарегистрировать кошелёк по ссылке https://tonwallet.me?testnet=true
Затем попросить в телеграм-канале https://t.me/tondev перевести вам немного TON (5 будет достаточно)
Или напишите мне (@ProjectManageRR), отправлю если буду доступен
21. Активируем наш смарт-контракт (очень грубо говоря - привяжем код смарт-контракта к кошельку):
/usr/bin/ton/lite-client/lite-client -C /usr/bin/ton/testnet-global.config.json -c "sendfile /srv/HelloWorldSC/sc.boc"
22. Вызываем функцию hello_world нашего смарт-контракта, и получаем в ответ 1234567890:
/usr/bin/ton/lite-client/lite-client -C /usr/bin/ton/testnet-global.config.json -c "runmethod АДРЕС_СМАРТКОНТРАКТА hello_world"
Если в ответе вы получили "..result: [ 1234567890 ].." - поздравляю! У Вас получилось развернуть смарт-контракт в сети TON! 🥳🥳
Bonus:
Пропишите "ls" в консоли и увидите след. файлы:
sc.addr - файл с адресом смарт-контракта
sc.boc - файл который мы отправили для активации смарт-контракта
sc.fc - файл с кодом смарт-контракта на языке FunC
sc.fif - скомпилированный sc.fc в код смарт-контракта на языке Fift
sc.pk - приватный ключ для доступа к смарт-контракту (например для перевода с него монет)
Обычно сохраняют .addr и .pk файлы в надёжное место, чтобы всегда была возможность иметь доступ.
Чуть позже я построчно разберу код использованного в гайде смарт-контракта (sc.fc), и прикреплю сюда ссылку вместо этого сообщения 😉
Если что-то не получилось по текущему гайду - обращайтесь @ProjectManageRR
Благодарен лайкам: EQAoB3Myz9p5DMjdAytez_d4FcWcXEnqRL7Mk11jS6PW0_R1
👍