Medindo o desempenho do SNARK: Frontends, backends e o futuro PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.

Medindo o desempenho do SNARK: Frontends, backends e o futuro

Um SNARK (Sucinct Non-Interactive Arguments of Knowledge) é uma importante primitiva criptográfica que encontra aplicações para escalabilidade de blockchain (por exemplo, rollups L2) e privacidade. SNARKs permitem que alguém prove a um verificador não confiável V (por exemplo, o blockchain Ethereum) que eles conhecem alguns dados (por exemplo, um lote de transações válidas). Uma maneira ingênua de provar isso seria enviar os dados para V, que pode então verificar diretamente sua validade. Um SNARK consegue o mesmo, mas com melhores custos para V. Em particular, uma prova SNARK deve ser mais curta do que a ingênua que compreende os próprios dados. (Para mais detalhes, veja o rascunho do meu livro, Provas, argumentos e conhecimento zero. Para uma introdução aos SNARKs, veja Sarah Meicklejohn's apresentação de negócios na criptografia a16z Série de Pesquisa de Verão.)

Os custos de verificação para SNARKs podem variar, mas são bem compreendidos e geralmente muito bons. Por exemplo, PlonK as provas custam cerca de 290,000 gás para verificar no Ethereum, enquanto as provas da StarkWare custam cerca de 5 milhões de gás. SNARKs são potencialmente aplicáveis ​​em diversas configurações, mesmo fora de blockchains - por exemplo, permitindo o uso de aplicativos rápidos, mas não confiáveis. Servidores e Hardwares

Mas como a verificação SNARK é tipicamente barata, os principais determinantes da aplicabilidade são os custos do provador SNARK P. Neste post, explico como estimar esses custos para determinar quando é razoável usar SNARKs e como os SNARKs podem melhorar no futuro. Vale a pena notar que este é um espaço em movimento rápido, e vários dos projetos discutidos neste post estão melhorando ativamente seu desempenho.

Mas primeiro: como os SNARKs são implantados

Na implantação do SNARK, um desenvolvedor normalmente escreve um programa de computador ψ que recebe como entrada os dados w que o provador afirma saber (w é um anagrama para testemunha), e verifica se w é válido. Por exemplo, em rollups, o programa verificará se todas as transações em w são assinados digitalmente, não fazem com que os saldos das contas fiquem abaixo de zero e assim por diante. O programa ψ é então alimentado através de um Interface SNARK que o compila em um formato mais acessível à aplicação da tecnologia SNARK. Este formato compatível com SNARK é chamado de representação intermediária (IR). 

Normalmente, o IR é algum tipo de instância de satisfatibilidade de circuito que é equivalente a ψ. Isso significa que o circuito C toma como entrada os dados w, bem como algumas entradas extras normalmente chamadas de “conselhos não determinísticos”, e executa ψ on w. As entradas de aconselhamento são usadas para ajudar C corrida ψ, Enquanto mantém C pequena. Por exemplo, cada vez ψ divide dois números x e y, o quociente q e restante r pode ser fornecido como aconselhamento para C e C pode simplesmente verificar que x = qy + r. Este cheque é mais barato do que fazer C executar um algoritmo de divisão para calcular q e r do princípio.

Finalmente, um SNARK para satisfatibilidade do circuito é aplicado a C. Isso é chamado de SNARK back-end. Para um punhado de problemas altamente estruturados, como multiplicação da matriz, circunvoluções e vários problemas gráficos, existem SNARKs conhecidos que evitam esse paradigma frontend/backend e, assim, alcançam um provador muito mais rápido. Mas o foco deste post é em SNARKs de uso geral.

Como veremos, os custos de prova do backend SNARK crescem com C's Tamanho. Guardando C small pode ser um desafio, porque os circuitos são um formato extremamente limitado para expressar uma computação. Eles consistem em portões, conectado por fios. Cada portão g é alimentado com alguns valores e aplica um muito função simples para esses valores. O resultado é então alimentado em portas “a jusante” através dos fios que emanam de g.

Escalabilidade SNARK: Quanto tempo realmente leva?

A questão-chave é: quanto tempo mais demora o provador SNARK, em relação a simplesmente reexecutar ψ nos dados? A resposta é o sobrecarga do provador do SNARK, em relação verificação direta de testemunhas. A última expressão refere-se ao fato de que, na prova ingênua em que P envia w para V, V cheques wvalidade de , executando ψ nele. 

É útil dividir a sobrecarga do provador em “sobrecarga de front-end” e “sobrecarga de back-end”. Se avaliar o circuito C portão a portão é F vezes mais caro do que correr ψ, então dizemos que a sobrecarga do frontend é F. Se aplicar o provador de back-end para C is B vezes mais caro do que avaliar C portão por portão, então dizemos que a sobrecarga de back-end é B. A sobrecarga total do provador é a produto, F·B. Essa sobrecarga multiplicativa pode ser substancial mesmo se F e B são individualmente modestos. 

Na prática, F e B ambos podem ser aproximadamente 1000 ou maiores. Isso significa que a sobrecarga total do provador em relação à verificação direta de testemunhas pode ser de 1 milhão a 10 milhões ou mais. Um programa executado por apenas um segundo em um laptop pode facilmente levar a um provador SNARK que exige dezenas ou centenas de dias de tempo de computação (single-thread). Felizmente, este trabalho é tipicamente paralelizável em várias extensões (dependendo do SNARK). 

Em resumo, se você quiser usar um SNARK em um aplicativo hoje, uma das três coisas precisa ser verdadeira:

  1. A verificação direta de testemunhas leva muito menos de um segundo em um laptop.
  2. A verificação direta de testemunhas é particularmente favorável à representação em um circuito, portanto, a sobrecarga de front-end é pequena.
  3. Você está disposto a esperar dias para que o provador SNARK termine e/ou pagar por enormes recursos de computação paralela.

TO restante deste post explica de onde vêm os overheads de front-end e back-end e como eu os estimo para diferentes SNARKs. Vamos então nos voltar para as perspectivas de melhoria. 

Separando front-ends e back-ends

Separar completamente os frontends dos backends pode ser um desafio porque diferentes backends suportam diferentes tipos de circuitos. Portanto, os front-ends podem diferir dependendo do back-end com o qual esperam fazer interface.

Os backends SNARK geralmente suportam os chamados circuitos aritméticos, o que significa que as entradas para os circuitos são elementos de algum campo finito e que as portas do circuito realizam adição e multiplicação de dois elementos de campo. Esses circuitos correspondem aproximadamente a programas de computador de linha reta (sem ramificações, declarações condicionais e assim por diante) que são de natureza algébrica - ou seja, seu tipo de dados primitivo é elementos de campo. 

A maioria dos back-ends realmente suporta uma generalização de circuitos aritméticos, muitas vezes chamados de instâncias de satisfação de restrição de classificação 1 (R1CS). Com a notável exceção de Groth16 e seus predecessores, esses SNARKs podem ser feitos para suportar outros IRs também. Por exemplo, StarkWare usa algo chamado Representação Intermediária Algébrica (AIR), que também é semelhante a uma noção chamada Aritmetização PlonKish que pode ser suportado pelo PlonK e outros backends. A capacidade de alguns back-ends de oferecer suporte a IRs mais gerais pode reduzir a sobrecarga de front-ends que produzem esses IRs. 

Os back-ends também variam em termos dos campos finitos que eles suportam nativamente. Discutirei isso melhor na próxima seção.

Várias abordagens para frontends

Alguns programas de computador (muito especiais) correspondem naturalmente a circuitos aritméticos. Um exemplo é o programa de computador que realiza a multiplicação ingênua de matrizes sobre algum campo. Mas a maioria dos programas de computador não são lineares nem algébricos. Eles geralmente envolvem instruções condicionais, operações como divisão de inteiros ou aritmética de ponto flutuante que não correspondem naturalmente à aritmética de campo finito e muito mais. Nesses casos, a sobrecarga do frontend será substancial. 

Uma abordagem de front-end popular é produzir circuitos que essencialmente executam passo a passo uma CPU simples, também chamada de máquina virtual (VM). Os designers de front-end especificam um conjunto de “operações primitivas” análogas às instruções de montagem para processadores de computador reais. Os desenvolvedores que desejam usar o frontend escreverão “programas de verificação de testemunhas” diretamente na linguagem assembly ou em alguma linguagem de nível superior, como Solidity, e terão seus programas compilados automaticamente em código assembly. 

Por exemplo, a StarkWare Cairo é uma linguagem assembly muito limitada na qual as instruções assembly permitem aproximadamente adição e multiplicação em um campo finito, chamadas de função e leituras e gravações em uma memória imutável (isto é, gravação única). O Cairo VM é uma arquitetura von Neumann, o que significa que os circuitos produzidos pelo frontend essencialmente pegam um programa Cairo como entrada pública e “executam” o programa na testemunha. A linguagem do Cairo é a Turing Complete — apesar de seu conjunto de instruções limitado, ela pode simular mais arquiteturas padrão, embora isso possa ser caro. O frontend do Cairo transforma os programas do Cairo em execução T instruções primitivas para o que é chamado de “grau-2 AR com T linhas e sobre 50 colunas”. o que exatamente isso significa não é importante para este post, mas no que diz respeito aos provadores SNARK, isso corresponde a circuitos com entre 50 e 100 portas para cada um dos T passos da CPU Cairo. 

RISC Zero adota uma abordagem semelhante ao Cairo, mas com a máquina virtual sendo a chamada Arquitetura RISC-V, uma arquitetura de código aberto com um rico ecossistema de software que está crescendo em popularidade. Como um conjunto de instruções muito simples, projetar um frontend SNARK eficiente que o suporte pode ser relativamente tratável (pelo menos em relação a arquiteturas complicadas, como x86 ou ARM). A partir de maio, RISC Zero está virando programas executando T instruções RISC-V primitivas em AIRs de grau 5 com 3T linhas e 160 colunas. Isso corresponde a circuitos com pelo menos 500 portas por etapa da CPU RISC-V. Outras melhorias são esperadas em um futuro próximo.

Os vários projetos zkEVM (por exemplo, zkSync 2.0, Scroll, zkEVM da Polygon) consideram a máquina virtual (duh) a Máquina Virtual Ethereum. O processo de transformar cada instrução EVM em um “gadget” equivalente (ou seja, um circuito otimizado implementando a instrução) é substancialmente mais complexo do que para as arquiteturas Cairo e RISC-V mais simples. Por este e outros motivos, alguns dos projetos zkEVM não estão implementando diretamente o conjunto de instruções EVM, mas compilando programas Solidity de alto nível em outras linguagens assembly antes de transformá-los em circuitos. Os resultados de desempenho desses projetos estão pendentes.

Projetos de “emulador de CPU” como RISC-V e Cairo produzem um único circuito que pode lidar com todos os programas na linguagem assembly associada. Abordagens alternativas são “tipo ASIC”, produzindo circuitos diferentes para programas diferentes. Essa abordagem do tipo ASIC pode produzir circuitos menores para alguns programas, especialmente quando a instrução de montagem que o programa executa em cada passo de tempo não depende da entrada do programa. Por exemplo, ele pode potencialmente evitar a sobrecarga de frontend inteiramente para programas de linha reta, como multiplicação de matrizes ingênuas. Mas a abordagem ASIC também parece altamente limitada; até onde eu sei, não se sabe como usá-lo para dar suporte a loops sem limites de iteração predeterminados. 

O componente final do overhead de frontend vem do fato de que todos os SNARKs usam circuitos que operam em campos finitos. A CPU do seu laptop pode multiplicar ou adicionar dois números inteiros com uma única instrução de máquina. Se um frontend emitir um circuito em um campo de característica grande o suficiente, ele pode essencialmente simular essa multiplicação ou adição por meio da operação de campo correspondente. No entanto, implementar a operação de campo em uma CPU real normalmente exigirá muitas instruções de máquina (embora alguns processadores modernos tenham suporte nativo para determinados campos). 

Alguns back-ends SNARK permitem escolhas de campo mais flexíveis do que outros. Por exemplo, se o back-end fizer uso de um grupo criptográfico G, o campo do circuito deve corresponder ao número de elementos em G, o que pode ser limitante. Além disso, nem todos os campos suportam algoritmos FFT práticos. 

Existe apenas um SNARK implementado, Travar, que suporta nativamente cálculos em campos arbitrários (grandes o suficiente). Junto com sua descendentes, ele tem o desempenho de provador de concreto mais rápido conhecido, mesmo em campos que outros SNARKs suportam, mas suas provas são atualmente muito grandes para muitas aplicações de blockchain. Trabalho recente procura melhorar o tamanho da prova, mas o provador é assintoticamente mais lento e parece ser barreiras à praticidade.

Alguns projetos optaram por trabalhar em campos com aritmética particularmente rápida. Por exemplo, Plonky2 e outros usam um campo de característica 264 - 232 + 1 porque a aritmética neste campo pode ser implementada várias vezes mais rápido do que em campos menos estruturados. No entanto, o uso de uma característica tão pequena pode levar a desafios na representação eficiente da aritmética de inteiros por meio de operações de campo (por exemplo, a multiplicação de dois inteiros sem sinal de 32 bits pode produzir um resultado maior que a característica do campo). 

 Mas não importa o que aconteça, para todos os SNARKs populares hoje alcançarem 128 bits de segurança (sem um aumento significativo nos custos de verificação), eles precisam trabalhar em um campo de tamanho maior que 2128. Até onde sei, isso significa que cada operação de campo exigirá pelo menos cerca de dez multiplicações de máquina de 64 bits e consideravelmente mais adições e operações bit a bit. Portanto, deve-se levar em consideração pelo menos uma ordem de magnitude de sobrecarga de front-end devido à necessidade de circuitos que operam em campos finitos. 

Para resumir, os frontends existentes que usam uma abstração de máquina virtual produzem circuitos com portas de 100x a 1000x por etapa da máquina virtual e possivelmente mais para máquinas virtuais mais complicadas. Além disso, a aritmética de campo finito é pelo menos 10x mais lenta do que instruções análogas em processadores modernos (com possíveis exceções se o processador tiver suporte interno para determinados campos). Uma “abordagem de front-end ASIC” pode reduzir algumas dessas sobrecargas, mas atualmente é limitada nos tipos de programas que pode suportar.

Quais são os gargalos de back-end?

SNARKs para satisfatibilidade de circuito são normalmente projetados combinando um protocolo de informação teoricamente seguro chamado “PIO polinomial” com um protocolo criptográfico chamado “esquema de compromisso polinomial.” Na maioria dos casos, o gargalo concreto para o provador é o esquema de compromisso polinomial. Em particular, esses SNARKs têm o provador comprometido criptograficamente com um ou mais polinômios cujo grau é (pelo menos) |C|, o número de portas no circuito C

Por sua vez, o gargalo concreto dentro do esquema de comprometimento polinomial dependerá do esquema utilizado e do tamanho do circuito. Mas sempre será uma das três operações a seguir: computar FFTs, exponenciações em um grupo criptográfico ou Hash Merkle. O hashing de Merkle normalmente é um gargalo apenas se o circuito for pequeno, portanto, não o discutiremos mais. 

Compromissos polinomiais baseados em log discreto

Em compromissos polinomiais baseados na dureza do problema do logaritmo discreto em um grupo criptográfico G (KZG, Bulletproofs, alfaquim e Hyrax-commit), o provador tem que calcular um Compromisso do vetor Pedersen aos coeficientes do polinômio. Isso envolve uma multi-exponenciação, de tamanho igual ao grau do polinômio. Em SNARKs, este grau é tipicamente o tamanho |C| do circuito C.

Feito ingenuamente, uma multi-exponenciação de tamanho |C| requer cerca de 1.5·|C|·log |G| 400·|C| operações em grupo, onde |G| denota o número de elementos no grupo G. No entanto, existe uma abordagem, chamada algoritmo de Pippenger, que pode reduzir isso por um fator de aproximadamente log |C|. Para circuitos grandes (digamos, |C| ≥ 225), este registro |C| pode ser concretamente 25 ou mais, ou seja, para grandes circuitos, esperamos que o compromisso vetorial de Pedersen seja computável com pouco mais de 10·|C| operações do grupo. Cada operação de grupo, por sua vez, tende a ser (como uma estimativa muito grosseira) cerca de 10 vezes mais lenta do que uma operação de campo finito. SNARKs usando esses compromissos polinomiais são tão caros para P como cerca de 100·|C| operações em campo. 

Infelizmente, os SNARKs existentes têm overheads adicionais além do fator 100x acima. Por exemplo:

  • espartanoO provador de , que usa o compromisso polinomial de Hyrax, tem a ver |C|½ muitas multi-exponenciações cada uma de tamanho |C|½, enfraquecendo a aceleração do algoritmo de Pippenger por um fator de aproximadamente dois. 
  • In Groth16, P deve funcionar em um grupo compatível com emparelhamento, cujas operações são normalmente pelo menos 2x mais lentas do que grupos que não são compatíveis com emparelhamento. P também deve executar 3 multi-exponenciações em vez de 1. Combinado, isso resulta em pelo menos um fator-6 adicional de desaceleração em relação aos 100·|C| estimativa acima. 
  • Marlin e PlonK também exigem emparelhamentos, e seus provadores se comprometem com consideravelmente mais de 3 polinômios. 
  • Para qualquer SNARK que usa Bulletproofs (por exemplo, Halo2, que é aproximadamente PlonK, mas com compromissos polinomiais Bulletproofs em vez de KZG), o provador precisa calcular logaritmicamente muitas multi-exponenciações durante a fase de “abertura” do esquema de compromisso, e isso apaga em grande parte qualquer aceleração Pippenger. 

Em resumo, SNARKs conhecidos usando compromissos de vetor Pedersen parecem ter uma sobrecarga de back-end de pelo menos 200x e até 1000x ou mais. 

Outros compromissos polinomiais

Para SNARKs usando outros compromissos polinomiais (como Sexta-feira e Ligero-commit), o gargalo é que o provador precisa realizar grandes FFTs. Por exemplo, nos AIRs de grau 2 produzidos pelo Cairo (com 51 colunas e T linhas, uma por etapa da CPU Cairo), o provador implantado da StarkWare faz pelo menos 2 FFTs por coluna, de comprimento entre 16 ·T e 32 ·T. As constantes 16 e 32 dependem dos parâmetros internos do FRI conforme definidos pela StarkWare e podem ser reduzidos — mas ao custo de maiores custos de verificação. 

Otimisticamente, uma FFT de comprimento 32·T leva cerca de 64·T·registro(32T) multiplicações de campo. Isso significa que mesmo para valores relativamente pequenos de T (por exemplo, T 220), o número de operações de campo por coluna é de pelo menos 64·25·T= 1600·T. Portanto, a sobrecarga de back-end parece estar na casa dos milhares. Além disso, é possível que grandes FFTs sejam ainda mais limitadas pela largura de banda da memória do que pelas operações de campo. 

Em alguns contextos, a sobrecarga de back-end de SNARKs que executam grandes FFTs pode ser mitigada com uma técnica chamada de agregação de prova. Para rollups, isso significaria que P (o serviço de rollup) divide um grande lote de transações em, digamos, 10 lotes menores. Para cada pequeno lote i, P produz uma prova SNARK πi da validade do lote. Mas P não publica essas provas no Ethereum, pois isso levaria a um aumento de quase 10 vezes nos custos do gás. Em vez disso, o SNARK é aplicado mais uma vez, desta vez para produzir uma prova π estabelecendo que P sabe π1 ...,π10. Ou seja, a testemunha que P afirma saber são as dez provas π1,…,π10, e a verificação direta de testemunhas aplica o procedimento de verificação SNARK a cada uma das provas. Esta prova única π é postado no Ethereum. 

Em compromissos polinomiais como FRI e Ligero-commit, há uma forte tensão entre P tempo e V custos, com parâmetros internos atuando como um botão que pode trocar um pelo outro. Desde π1 ,…,π10 não são postados no Ethereum, o botão pode ser ajustado para que essas provas são grandes, e produzi-los é mais rápido. Somente na aplicação final do SNARK, para agregar π1 ,…,π10 em uma única prova π, o esquema de compromisso precisa ser configurado para garantir uma pequena prova. 

StarkWare planeja implantar agregação de prova iminentemente. Este também é o foco de projetos como Plonky2.

Quais são os outros gargalos para a escalabilidade SNARK?

Este post tem como foco o provador tempo, mas outros custos do provador também podem ser gargalos de escalabilidade. Por exemplo, para muitos backends SNARK, o provador precisa armazenar vários elementos de campo para cada porta em C, e esse custo de espaço pode ser enorme. Por exemplo, um programa ψ rodando em um segundo em um laptop pode realizar talvez um bilhão de operações primitivas em um processador moderno. Como vimos, em geral, deve-se esperar C exigir bem mais de 100 portões por tal operação. Isso significa 100 bilhões de portões, o que, dependendo do SNARK, pode significar dezenas ou centenas de terabytes de espaço para P

Outro exemplo: muitos SNARKs populares (por exemplo, PlonK, Marlin, Groth16) exigem uma complicada "cerimônia de configuração confiável" para gerar uma "chave de comprovação" estruturada que deve ser armazenado pelo provador. Pelo que sei, o maior tal cerimônia gerou uma chave de prova capaz de suportar circuitos com cerca de 228250 milhões de portões. A chave de prova tem várias dezenas de gigabytes de tamanho. 

Em contextos em que a agregação de provas é possível, esses gargalos podem ser substancialmente mitigados. 

Olhando para o futuro: perspectivas para SNARKs mais escaláveis

As despesas gerais de front-end e back-end podem ser de três ordens de magnitude ou mais. Podemos esperar que eles diminuam substancialmente no futuro próximo? 

Acho que vamos – até certo ponto. Primeiro, os back-ends mais rápidos hoje (por exemplo, espartano e Travar, e outros SNARKs que combinam o protocolo de verificação de soma com compromissos polinomiais) têm grandes provas - normalmente raiz quadrada no tamanho do circuito - então as pessoas não estão realmente usando. Espero que o tamanho da prova e o tempo do verificador sejam significativamente reduzidos em um futuro próximo por meio da composição de profundidade um com SNARKs de prova pequena. Semelhante à agregação de prova, isso significa que um provador geraria primeiro uma prova SNARK π com o SNARK “provador rápido, prova grande”, mas não enviar π para V. Em vez, P usaria um SNARK de prova pequena para produzir uma prova π, que ele sabe π, e envia π' para V. Isso pode reduzir uma ordem de magnitude das despesas gerais de back-end dos SNARKs que são populares hoje. 

Em segundo lugar, a aceleração de hardware pode ajudar. Uma regra geral muito grosseira é que as GPUs podem comprar uma aceleração de 10x sobre as CPUs e os ASICs uma aceleração de 10x sobre as GPUs. No entanto, tenho três preocupações nesta frente. Primeiro, grandes FFTs podem ser afunilados pela largura de banda da memória em vez de operações de campo, então SNARKs que executam tais FFTs podem ver acelerações limitadas de hardware especializado. Em segundo lugar, enquanto este post se concentrou no gargalo do compromisso polinomial, muitos SNARKs exigem que o provador faça outras operações que são apenas um pouco menos caras. Portanto, quebrar o gargalo de comprometimento polinomial (por exemplo, acelerando multi-exponenciações em SNARKs baseados em logs discretos) pode deixar uma nova operação de gargalo que não é muito melhor que a antiga. (Por exemplo, SNARKs incluindo Groth16, Marlin e PlonK também têm o provador de FFTs, além de multi-exponenciações.) Finalmente, os campos e curvas elípticas que levam aos SNARKs mais eficientes podem continuar a evoluir por algum tempo, e isso pode criar desafios para a aceleração do provador baseado em ASIC.

No lado do frontend, podemos descobrir cada vez mais que a abordagem de “emulador de CPU” de projetos como Cairo, RISC Zero, zkEVMs e outros realmente escala muito bem (em termos de desempenho) com a complexidade dos conjuntos de instruções da CPU. De fato, esta é precisamente a esperança de vários projetos zkEVM. Isso pode significar que, enquanto a sobrecarga do frontend permanece três ordens de magnitude ou mais, os frontends conseguem suportar VMs que correspondem cada vez mais às arquiteturas de CPU reais. Uma preocupação compensatória é que os frontends podem se tornar complicados e difíceis de auditar, à medida que se proliferam dispositivos codificados à mão que implementam instruções cada vez mais complicadas. Os métodos formais de verificação provavelmente desempenharão um papel importante na abordagem dessa preocupação. 

Finalmente, pelo menos em aplicativos blockchain, podemos descobrir que a maioria dos contratos inteligentes que aparecem na natureza usam principalmente instruções simples e amigáveis ​​​​ao SNARK. Isso pode permitir baixas despesas gerais de front-end na prática, mantendo a generalidade e a experiência aprimorada do desenvolvedor que vem com o suporte a linguagens de programação de alto nível como Solidity e conjuntos de instruções ricos, incluindo os do EVM. 

***

Justin Thaler is Professor Associado da Universidade de Georgetown. Antes de ingressar na Georgetown, ele passou dois anos como Cientista de Pesquisa no Yahoo Labs em Nova York, antes dos quais foi Pesquisador no Instituto Simons para a Teoria da Computação na Universidade de Berkeley. 

***

Agradecimentos: Sou grato a Elena Burguer por propor o tema deste post, e por Arasu Arun, José Bonneau e Sam Ragsdale para comentários perspicazes. Agradecimentos especiais também ao meu editor, Tim Sullivan.

***

As opiniões expressas aqui são as do pessoal individual da AH Capital Management, LLC (“a16z”) citadas e não são as opiniões da a16z ou de suas afiliadas. Certas informações aqui contidas foram obtidas de fontes de terceiros, inclusive de empresas do portfólio de fundos administrados pela a16z. Embora retiradas de fontes consideradas confiáveis, a16z não verificou essas informações de forma independente e não faz representações sobre a precisão duradoura das informações ou sua adequação a uma determinada situação. Além disso, esse conteúdo pode incluir anúncios de terceiros; a16z não revisou tais anúncios e não endossa nenhum conteúdo de publicidade neles contido.

Este conteúdo é fornecido apenas para fins informativos e não deve ser considerado como aconselhamento jurídico, comercial, de investimento ou fiscal. Você deve consultar seus próprios conselheiros sobre esses assuntos. As referências a quaisquer valores mobiliários ou ativos digitais são apenas para fins ilustrativos e não constituem uma recomendação de investimento ou oferta para fornecer serviços de consultoria de investimento. Além disso, este conteúdo não é direcionado nem destinado ao uso por quaisquer investidores ou potenciais investidores, e não pode, em nenhuma circunstância, ser invocado ao tomar uma decisão de investir em qualquer fundo administrado pela a16z. (Uma oferta para investir em um fundo a16z será feita apenas pelo memorando de colocação privada, contrato de subscrição e outra documentação relevante de tal fundo e deve ser lida na íntegra.) Quaisquer investimentos ou empresas de portfólio mencionados, referidos ou descritos não são representativos de todos os investimentos em veículos administrados pela a16z, e não pode haver garantia de que os investimentos serão rentáveis ​​ou que outros investimentos realizados no futuro terão características ou resultados semelhantes. Uma lista de investimentos feitos por fundos administrados por Andreessen Horowitz (excluindo investimentos para os quais o emissor não deu permissão para a a16z divulgar publicamente, bem como investimentos não anunciados em ativos digitais negociados publicamente) está disponível em https://a16z.com/investments /.

Os gráficos e gráficos fornecidos são apenas para fins informativos e não devem ser considerados ao tomar qualquer decisão de investimento. O desempenho passado não é indicativo de resultados futuros. O conteúdo fala apenas a partir da data indicada. Quaisquer projeções, estimativas, previsões, metas, perspectivas e/ou opiniões expressas nestes materiais estão sujeitas a alterações sem aviso prévio e podem diferir ou ser contrárias às opiniões expressas por outros. Consulte https://a16z.com/disclosures para obter informações adicionais importantes.

Carimbo de hora:

Mais de Andreessen Horowitz