O desenvolvedor Christophe Verdot compartilha suas experiências de fazer recentemente o curso on-line
'Mastering Web 3.0 with Waves' .
Qual é a sua formação? O que o motivou a fazer o curso?Sou desenvolvedor web há cerca de 15 anos, trabalhando principalmente como freelancer.
Trabalhando no desenvolvimento de aplicativos da web de registro sustentável para países emergentes, financiados por um grupo de bancos, uma vez me perguntaram sobre a possibilidade de implementar a certificação blockchain no registro. Naquela época, eu não sabia muito sobre a certificação blockchain, apesar de estar em cripto há algum tempo, principalmente do lado dos investidores.
Não avançamos com a implementação desse recurso nesse aplicativo específico, mas a idéia de que instituições e bancos estavam perguntando sobre a implementação de tais tecnologias em seus aplicativos me fez estudar e pesquisar bastante o tópico e iniciar a
Cadeia de Assinaturas. projeto.
Eu desenvolvi uma versão beta que já está ativa na Mainnet. Naquela época, a [linguagem de programação Waves] Ride ainda não estava pronta, então eu a desenvolvi da maneira mais simples, usando transações de transferência com JSON anexado. Mas o objetivo principal sempre foi oferecer recursos mais avançados assim que o Ride estivesse disponível. E esse foi o principal motivo para eu seguir o curso, pois a próxima etapa planejada do projeto é transformá-lo em um aplicativo descentralizado (dApp).
Quais aspectos do curso você achou mais fácil e mais difícil?O aspecto mais fácil era que tínhamos tempo suficiente para fazê-lo, que era apenas aprender e não competir para ser o melhor. Também foi bem explicado, com ilustrações simples, mas explícitas, que ajudaram muito a visualizar e entender diferentes tópicos.
Nos desafios, fomos levados a pensar por conta própria e, às vezes, fazer alguma pesquisa, que é a melhor maneira de aprender e obter uma compreensão mais forte dos conceitos de uma lição.
Várias vezes, eu não entendi claramente a parte da palestra até entrar no código e passar pelo desafio. Não foi permitido copiar / colar, o que nos forçou a escrever todo o código do desafio, e esse foi outro ponto importante para reforçar o entendimento.
A parte mais difícil foi que às vezes as perguntas de múltipla escolha na parte do desafio não eram tão claras. Quero dizer, meu inglês não é excelente, e as perguntas foram escritas por um falante não-nativo de inglês, então havia uma lacuna no entendimento algumas vezes.
Provavelmente, eu gostaria de aprender mais com as seções oracle e NFT. Mas, em qualquer caso, este curso visa principalmente atrair os desenvolvedores, e você definitivamente precisa gastar tempo brincando com ele e praticando mais tarde para realmente obter uma compreensão completa de todos os aspectos e detalhes.
Você poderia discutir em detalhes a solução em que trabalhou durante o curso - 'Coupon Bazaar'? Você também pode fornecer exemplos de código?Trabalhamos no 'Coupon Bazaar', que é basicamente um mercado em que as pessoas compram e vendem cupons de desconto para bens e serviços a um preço baixo. Cada cupom foi representado por um ativo digital, que também representou um desconto especial oferecido pelos fornecedores.

Foi necessário trabalho em vários componentes do aplicativo. Primeiro, era necessário permitir que os fornecedores registrassem e gerenciassem seus itens (cupons). Em seguida, era necessário criar um recurso de confirmação de compra, bem como um recurso que permitisse aos clientes pesquisar e comprar cupons.

Vários recursos extras também foram adicionados durante o curso, incluindo um sistema de votação e um recurso para verificação e lista negra de fornecedores.
Primeiro, analisamos as diferenças entre os ativos inteligentes, as contas inteligentes e as contas do dApp e os fundamentos do trabalho com as funções do verificador. As funções do verificador permitem alterar o comportamento padrão de uma conta. Por padrão, eles verificam assinaturas de transações, mas a função verificador permite definir outra 'regra'.
{-# STDLIB_VERSION 3 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} letownerPublicKey = base58'H8ndsHjBha6oJBQQx33zqbP5wi8sQP7hwgjzWUv3q95M' @Verifier(tx) funcverify() = { matchtx { cases: SetScriptTransaction=>sigVerify(tx.bodyBytes, tx.proofs[0], ownerPublicKey) cased: DataTransaction=>true case_ =>false } }
Então começamos a adicionar itens. Usamos um dos recursos mais importantes para o desenvolvimento do dApp que permite que qualquer tipo de dado seja registrado no blockchain como pares de valor-chave, a transação de dados. Combinamos isso com uma nova transação, invokeScript, usada para chamar uma função que pode ser chamada em um dApp de fora.
Um tipo de transação de dados que usamos no curso foi para os fornecedores adicionarem itens ao mercado:
letdatajson = { "title": "t-shirt with , vote 1", "coupon_price": 10000000, "old_price": 1000000000, "new_price": 100000000, "address": "Universe", "description": "I want you to make love, not war, i know you've heard it before", "image": "https://bit.ly/2EXTghg" } it('add item', asyncfunction(){ letts = invokeScript({ dApp: dappAddress, call:{ function:"addItem", args:[ { type:"string", value: datajson.title }, { type:"integer", value: datajson.coupon_price }, { type:"string", value: JSON.stringify(datajson) } ]}, payment: [] }, accountSupplierSeed) lettx = awaitbroadcast(ts) awaitwaitForTx(tx.id) })
Para processar essa transação de dados através da função addItem e, posteriormente, desenvolver uma compra e outras opções, passamos pela função que pode ser chamada, capaz de ser chamada pelos usuários de fora. Como resultado, ele pode executar várias tarefas, como iniciar a transferência de fundos, gravar ou atualizar dados no armazenamento de dados do dApp, etc.
Aqui está um exemplo de uma função que pode ser chamada. É usado para a função addItem:
@Callable(i) funcaddItem(title: String, price: Int, data: String) = { letsupplierAddress = toBase58String(i.caller.bytes) letitem = getKeyItem(supplierAddress, title) if( price <= 0) thenthrow("purchase amount cannot be less than item price") elseif( getValueItemSupplier(item) !=NONE ) thenthrow("an item is already exist") else{ WriteSet([ DataEntry(getKeyItemSupplier(item), supplierAddress), DataEntry(getKeyItemPrice(item), price), DataEntry(getKeyItemData(item), data) ]) } }
Mais tarde, trabalhamos em um sistema de votação para permitir que os usuários votem na promoção ou remoção de determinados produtos. Ele usou um esquema de "confirmação de confirmação" para evitar influência externa durante o processo de votação.
A etapa de confirmação foi usada para coletar votos criptografados com uma função hash e salt.
A etapa de revelação é coletar votos descriptografados e comparar seus hashes.
Aqui está um exemplo de uma função que pode ser chamada usada para esse recurso:
@Callable(i) funcvoteCommit(item: String, hash: String) = { letuser = toBase58String(i.caller.bytes) letcommits = getValueCommitsCount(item) letstatus = getValueItemStatus(item) if( commits >=VOTERS) thenthrow("reached max num of voters") elseif(getValueCommit(item, user) !=NONE) thenthrow("user has already participated") elseif(getKeyItemSupplier(item) ==NONE) thenthrow("item does not exist") elseif(status !=NONE && status !=VOTING) thenthrow("voting is not possible") else{ WriteSet([ DataEntry(getKeyCommit(item, user), hash), DataEntry(getKeyCommitsCount(item), commits +1), DataEntry(getKeyItemStatus(item),if(commits ==VOTERS) thenREVEAL elseVOTING) ]) } }
O que mais você aprendeu com o curso?O curso também abordou tokenização e tokens não fungíveis (NFTs) - tokens que representam algo único e, portanto, não são intercambiáveis.
A última aula focada no uso de oráculos. Como uma blockchain não pode acessar dados do mundo exterior, precisamos usar oráculos que enviam dados do mundo real para a blockchain.
No escopo de nosso mercado, usamos um oráculo para verificar e, se necessário, colocar na lista negra um fornecedor que, por exemplo, não aceitou um cupom vendido anteriormente.
Aqui está um exemplo de código:
funcgetExtValueItemWhiteListStatus(item:String) = { item +"_verifier_status" } letverifier = "3Mx9qgMyMhHt7WUZr6PsaXNfmydxMG7YMxv" letVERIFIED = "verified" letBLACKLISTED = "blacklist" @Callable(i) funcsetstatus(supplier: String, status: String) = { letaccount = toBase58String(i.caller.bytes) if( account !=verifier ) thenthrow("only oracle verifier are able to manage whitelist") elseif( status !=VERIFIED && status !=BLACKLISTED) thenthrow("wrong status") else{ WriteSet([ DataEntry(getExtValueItemWhiteListStatus(supplier), status) ]) } }
Que parte do curso você achou mais útil?A parte mais útil foram os desafios. Eles tornaram as palestras mais claras e solidificaram meu conhecimento recém-adquirido por tentativa e erro. Praticar com o
IDE ,
explorador e
oráculos foi realmente útil.
Como você planeja usar o que aprendeu no curso?Desde o início, este curso deveria ajudar a trazer meu projeto para o próximo nível. Portanto, a ideia agora é reescrever
sign-web.app no Ride. A versão atual já oferece recursos de trabalho para certificação de documentos, mas definitivamente será aprimorada com uma versão futura do Ride. Permitirá mais flexibilidade, clareza e mais recursos, incluindo certificação por e-mail, contrato com várias partes, etc.
O curso também foi muito revelador, e muitas idéias começaram a surgir na minha cabeça. Tenho certeza de que mais surgirão no futuro.